• 締切済み

C言語の意味

プログラミングの勉強をしています。 知り合いから,アルファベットの大文字を小文字に変換するプログラムについておしえてもらいました。 #include<stdio.h> #include<ctype.h> #define MCH 3 int main() { char chs[MCH]; printf("アルファベットの大文字を入力して下さい:"); fgets(chs,MCH,stdin); chs[1] = '\0'; printf("小文字は[%c]です。\n",tolower(*chs)); return 0; } この中で, 3行目の#define MCH 3 のdefineの意味 6行目のchar chs[MCH]; のchs・MCHの意味 9行目のchs[1]= '\0'; これ自体の設定がわかりません。 教えてもらえないでしょうか?

みんなの回答

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

>#3さん >chs[1], chs[2] には行末コードという特別な文字が入ります。 そうではありません。 chs[1]には'\n'が、chs[2]には'\0'が、それぞれ入ります。

  • 6yemon
  • ベストアンサー率69% (25/36)
回答No.3

> #define MCH 3 のdefineの意味 この場合 MCH という文字列は、すべて 3 に置き換えられます。 これはマクロの一番簡単な例です。 つまり、char chs[MCH]; という行は char chs[3]; になり、 fgets(chs, MCH, stdin); という行は fgets(chs, 3, stdin); と置き換えられ、それからコンパイルされます。 MCHという文字列(マクロ)を使わなくても同じプログラムができますが、 理由はともかく、マクロを使うと良いことがあるので、こうする習慣があります。 > 6行目のchar chs[MCH]; のchs・MCHの意味 上記の通り chs[MCH]; は chs[3]; と同じです。 ここでは、配列の大きさ(要素の数)が3である、 char(文字)型の配列変数を宣言してます。 キーボードでタイプしたキーをfgets()で読み込んでますが、 読み込んだ文字列を格納する場所として配列が必要なのです。 "chs", "MCH" という名前は、プログラムを書いた人が適当に決めた、固有名詞のようなものです。 > 9行目のchs[1]= '\0'; これ自体の設定がわかりません。 「設定」ではなく、この操作の意味がわからないのですね。 まず、chs[3] という配列には chs[0], chs[1], chs[2] と、 文字の入る場所が3つあります。 このプログラムを実行した時に、例えば A(とEnterキー)をタイプしたとすると、 chs[0] には 'A' が入る(格納される)わけです。 ただし格納されるのは、'A'一文字だけではありません。 ここで使っている、fgets() は、一文字ではなく、一行を入力する関数なので、chs[1], chs[2] には行末コードという特別な文字が入ります。 大文字をタイプするときに Enter キーも押しますよね。 行末コードとはEnterキーに対応する、特別な文字だと思えばよい。 行末コードは特別な文字ですが、 '\0' も特別な文字で、文字列の最後を示す文字です。 chs[1] = '\0'; という代入をすることによって、 chs[0] には 'A'が有り、chs[1]には(行末コードではなく)'\0' が入るわけですから、 その結果、chs[] 文字列配列には "A" という文字列が入った状態になります。 要するに、プログラムを作った方は、"A" という「文字列」が入った状態にしてから tolower(*chs) を実行したかったのでしょう。 ところが実は chs[1] = '\0'; をする必要はありません(この行を削除しても問題ない)。 何故なら、tolower() の引数は、文字列(配列)ではなく、 文字(この場合 chs[0] の一文字)だけで、 chs[1]には何が入っていても構わないからです。 ちなみに、*chs と chs[0] は、同じ意味になります。 …という説明ができますが、今の段階ではわからないことだらけでしょうね、きっと(笑)。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

まずは、その知り合いの方に、そのコードのこころについて 教えてもらうのがいいのではないでしょうか。 ここで解説したのと知り合いの方の意図とが食い違っていると、 よけいな混乱を招いてしまいそうです。

回答No.1

3行目の#define MCH 3 のdefineの意味 「MCHという言葉を3と定義する」ということです。 以降MCHの部分を3に置き換えればよいでしょう。 6行目のchar chs[MCH]; のchs・MCHの意味 MCHは3なので char chs[3]; ですね。 これで意味がわからないならば変数、配列の勉強をしなおさないと今後C言語を使うのは厳しいでしょう。 9行目のchs[1]= '\0'; これ自体の設定がわかりません。 最初の一文字以外は無視したかったのでしょう。 これで意味がわからないならばString型(文字列)変数の勉強をしなおしましょう。

関連するQ&A

  • C言語について教えてください。

    #include <ctype.h> #include <stdio.h> void name_toupper(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = toupper(istr[i]); i++; } ostr[i] = '\0'; } void name_tolower(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = tolower(istr[i]); i++; } ostr[i] = '\0'; } void name_change(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { if(isupper(istr[i])) { ostr[i] = tolower(istr[i]); } else { ostr[i] = toupper(istr[i]); } i++; } ostr[i] = '\0'; } int main(void) { char buffer[100]; char result[100]; printf("文字"); gets(buffer); name_toupper(buffer,result); printf("大文字: %s\n", result); name_tolower(buffer,result); printf("小文字: %s\n", result); name_change(buffer,result); printf("大小交換: %s\n", result); return 0; } 出力結果 文字abc DEFG 大文字: ABC DEFG 小文字: abc defg 大小交換: ABC defg 上のプログラムで文字関数isupperを用いずにプログラムする方法を教えてもらえませんか? もしくわ、用いずにプログラムすることは不可能ですか? 教えてください。 よろしくお願いします。

  • C言語ののポインタについて

    「明解C言語 入門編」p262の演習11-4についての質問です。 このサイトも参考にしてみて、 入力された文字の大文字小文字を反転するプログラムをvimで書いてみたのですが #include <stdio.h> #include <ctype.h> void str_toupper(char *str) { while (*str = toupper(*str)) { *str++; } } void str_tolower(char *str) { while(*str = tolower(*str)) { *str++; } } int main(void) { char str[100]; printf("文字列を入力してください:"); scanf("%s", str); str_toupper(str); printf("大文字:%s\n", str); str_tolower(str); printf("小文字:%s\n", str); return(0); } clangを用いてコンパイルすると4warnings generatedと出ます。 ------------------------------------------------------------ ex11-4.c:6:13: note: use '==' to turn this assignment into an equality comparison while(*str = toupper(*str)){ ^ ------------------------------------------------------------- こんなのや ---------------------------------------- ex11-4.c:7:3: warning: expression result unused [-Wunused-value] *str++; ^~~~~~ ---------------------------------------------------- といった警告が表示されます。 どこをどう訂正すれば良いのでしょうか。 よろしくお願いします。

  • C言語のプログラミングでつまずいてます

    ポインタをりようする。string.hとctype.hに含まれる関数は使用しないこと。 以下の実行例のように、文字列を受け取り、アルファベットの大文字を小文字にして表示する関数を作成したいのですが 実行例: Original string is <AbCdE1f2> Modified string is <abcde1f2> #include <stdio.h> #define NUMOFCHAR 10 void print_char(char *ptr); int main(void) { char string[NUMOFCHAR+1]; printf("Input a sentence (# of letters <= %d): ", NUMOFCHAR); fflush(stdout); scanf("%s", string); string[NUMOFCHAR] = '\0'; printf("Original string is <%s>\n", string); printf("Modified string is <"); print_char(string); printf(">\n"); return 0; } void print_char(char *ptr) { int i=0; for(i=0 ; i<NUMOFCHAR+1 ; i++){ if( *ptr>='A' && *ptr<='Z'){ *ptr += 'A'-'a' ; } ptr++ ; } printf("%s",ptr); } よ書いたのですがビルドえらーがおこります。 どこがだめなのかわかりません。。。 C言語に詳しい人でわかるかた、どこがいけないのか、なぜいけないのか、どうすればいいのか詳しくおしえてください。 お願いします

  • C言語の変換する関数について教えてください。

    キーボードからローマ字で入力された名前の英文字を変換する関数を定義し、その関数の機能を確認するプログラムを作成する問題について教えてください。 (1)英小文字であればそれを英大文字に変換する関数 (2)英大文字であればそれを英小文字に変換する関数 (3)英小文字であればそれを英大文字に、英大文字であればそれを英小文字に変換する関数 ただし、キーボードから入力された名前を格納する配列と、変換後の名前を格納する配列を別にする。 また、名前は関数main()内で表示する #include <ctype.h> #include <stdio.h> void name_toupper(char str[]) { unsigned i = 0; while (str[i]) { str[i] = toupper(str[i]); i++; } } void name_tolower(char str[]) { unsigned i = 0; while (str[i]) { str[i] = tolower(str[i]); i++; } } int main(void) { char str[100]; printf("文字"); scanf("%s", str); name_toupper(str); printf("大文字: %s\n", str); name_tolower(str); printf("小文字: %s\n", str); return 0; } 自分で作った上のプログラムではKa siと入力すると(1)ではKA、(2)ではkaと表示されsiが消えてしまいます。原因がよくわかりません。 あと(3)ができないし、ただしを満たしているのかもあいまいです。 文字列の入力の形式:char *gets(char *buffer)を用いればどうにかなるのではと思っていますがどうですか? 説明が長くなって申し訳ありませんが教えてください。 よろしくお願いします。

  • C言語のファイル読み込みに関して。

    英文を入力したテキストファイルを読み込むプログラムをつくっているのですが、 ファイル読み込みが上手くできません。 #include<stdio.h> main() { char filename[33]; char sty[512]; FILE *fp; printf("FILENAME: "); fgets(filename, 33, stdin); //読み込むテキストファイルを指定 fp = fopen(filename,"r"); if(fp == NULL){ printf("Can't open the file!\n"); return -1; } fgets(sty, 512, fp); fclose(fp); printf("%s\n",sty); } このプログラムなのですが、どうしても"Can't open the file!"が表示されてしまいます。 どうすればいいのでしょうか?

  • C言語についてなのですが・・・

    さきほども上げたのですがカテゴリが間違っていたのでもう一回書き込みました まだプログラムの勉強をはじめた初心者なのですが、 テキストファイルから文字を読みこみ、大文字ならば小文字に変換し辞書順に並びかえるプログラムを作っているのですがどうしてもうまくいきません。 例えばtest.txtに XXX YYY YY XX BBB aaa aa BB とあれば aa aaa bb bbb xx xxx yy yyy と表示されるよにしたいんです。 自分が作ったプログラむはこれです。 まだテキストファイルからでなくキーボードからの入力になっていますが・・・ #include<stdio.h> #include<stdlib.h> #include<string.h> #include <ctype.h> int soto( const void *x, const void *y); int main(int argc, char *argv[]){ FILE *input; char str1[1000]; int i, j; for (i = 1; i < argc; i++){ qsort(argv[i], 1000, sizeof( char *), soto); strcpy(str1, argv[i]); for(j = 0; j < 100; j++){ str1[j] = tolower( str1[j] ); } printf("%s\n", str1); } return 0; } int soto( const void *a, const void *b){ char *x, *y; x = (char*)a; y = (char*)b; return x-y; } これだと小文字にはなるんですがソートされずに表示されてしまいます・・・ どのようにすればいけるのかご指摘のほどおねがいします

  • C言語の変換する関数について教えてください。

    キーボードからローマ字で入力された名前の英文字を変換する関数を定義し、その関数の機能を確認するプログラムを作成する問題について教えてください。 (1)英小文字であればそれを英大文字に変換する関数 (2)英大文字であればそれを英小文字に変換する関数 (3)英小文字であればそれを英大文字に、英大文字であればそれを英小文字に変換する関数 ただし、キーボードから入力された名前を格納する配列と、変換後の名前を格納する配列を別にする。 また、名前は関数main()内で表示する。 #include <ctype.h> #include <stdio.h> void name_toupper(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = toupper(istr[i]); i++; } } void name_tolower(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = tolower(istr[i]); i++; } } void name_change(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { if(isupper(istr[i])) { ostr[i] = toupper(istr[i]); } else { ostr[i] = tolower(istr[i]); } i++; } } int main(void) { char buffer[100]; printf("文字"); gets(buffer); name_toupper(buffer); printf("大文字: %s\n", buffer); name_tolower(buffer); printf("小文字: %s\n", buffer); name_change(buffer); printf("大小交換: %s\n", buffer); return 0; } 上のプログラムでは、呼び出し時のパラメータが足りないとエラーが発生してしまいます。文字列を入れておく配列をbuffer以外にもう一つ作らなくてはいけないと思うのですが、うまくいきません。 教えてください。よろしくお願いします。

  • ソースコードの間違い (C言語)

    変数に、文字列を入れた配列の文字列の最後の要素数を入れたいのですが(つまり'\0')、うまくいきません。いつも2個多い値になってしまいます。 #include <stdio.h> void main() { char moji[100]={0}; int c=0; fgets(moji,sizeof moji,stdin); while( moji[c] != '\0' ) ++c; printf("\n%d\n",c); // } 例えば5文字の1ビット文字を入れると、最後の文字はmoji[4]にあるのでprintfで4と表示されるはずじゃないですか。でも6になるんです。いつも+2の値になるんですよ。どうやらfgetsを使っているからそうなるらしく、scanfを使うと結果は1多い値に、普通に配列に直接文字列を代入すると正常な結果になります。別にcに-2してもいいのですが、それはなんだか癪といいますか・・・。なぜこういうことがおきるのでしょうか?回答よろしくお願いします。

  • C言語の問題が解けません!

    僕は、C言語を勉強しているのですがこの問題の答えがわかりません。 どうか教えてください。 回答お願いします。 ・問題・ 10文字以内の2つの英単語を入力し、アルファベット順で最初にくる単語を表示するプログラムを作りなさい。 /プログラム/ #include<stdio.h> #include<string.h> int main(void) { char str1[256],str2[256]; int i; printf("文字列1は?"); printf("文字列2は?"); return 0; }

  • C言語の課題に取り組んでいるんですが・・・

    まだプログラムの勉強をはじめた初心者なのですが、 テキストファイルから文字を読みこみ、大文字ならば小文字に変換し辞書順に並びかえるプログラムを作っているのですがどうしてもうまくいきません。 例えばtest.txtに XXX YYY YY XX BBB aaa aa BB とあれば aa aaa bb bbb xx xxx yy yyy と表示されるよにしたいんです。 自分が作ったプログラむはこれです。 まだテキストファイルからでなくキーボードからの入力になっていますが・・・ #include<stdio.h> #include<stdlib.h> #include<string.h> #include <ctype.h> int soto( const void *x, const void *y); int main(int argc, char *argv[]){ FILE *input; char str1[1000]; int i, j; for (i = 1; i < argc; i++){ qsort(argv[i], 1000, sizeof( char *), soto); strcpy(str1, argv[i]); for(j = 0; j < 100; j++){ str1[j] = tolower( str1[j] ); } printf("%s\n", str1); } return 0; } int soto( const void *a, const void *b){ char *x, *y; x = (char*)a; y = (char*)b; return x-y; } これだと小文字にはなるんですがソートされずに表示されてしまいます・・・ どのようにすればいけるのかご指摘のほどおねがいします

専門家に質問してみよう