• ベストアンサー

getchar()を int でとる理由がわかりません

 今晩は、Cの初心者ですよろしくお願いします。    int ch;  ch=getchar();  を使う場合には、「ch」は「char」でなく「int」型でとるのが良いと本には書いていますが、何故かは書かれていません。  この理由はなぜでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

#2さんの答えに出ていますが、ようはエラー処理用です。 getchar()からはcharの範囲のデータを取得したいわけですが、Cではこの返り値はエラー処理にも使います。つまり、返り値がcharなのに返り値のひとつをエラー処理用に使うとすると、そのひとつが返ってきたときはエラーと判断され、使えなくなってしまうわけです。 エラー処理用に、charより広い範囲が欲しい・・・というのが返り値にintを使う本質的な理由でしょうね。 ちなみに、'a'と書いたとき、これ実はcharじゃなくてintです。 補足になりますが、ちょっと#2さんの方で誤解を招く表現がありますのでそちらについて一言。 -1はunsigned charとして解釈されるとき、unsigned charの最大値になります。-1って、バイナリレベルで見ればすべてのbitが立った状態ですので、unsignedにすれば最大値になるという寸法です。(ただし2の補数表現の場合。もし負数の表現に関して「1の補数表現」や「絶対値表現」を使っているときは、異なる結果となる可能性もあります) なので、「unsigned charは負数を認識できない」は偽です。しかしいずれにせよunsignedを相手に負数を使うとろくなことがないので、この点は注意するに越したことはありません。 unsigned char uch; uch = -1; /* uch == 255 */

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

おっと, #5 では「#3 への突っ込み」と書いてしまいましたがこれは間違いで, 正しくは「#4 への突っ込み」です. #3 さん&#4 さん, 申し訳ありません.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

まず getchar は「stdin から 1バイト読み込む」という働きをします. で機能を遡って行くと最終的に fgetc にたどり着きます. そして fgetc は「1文字 (fgetc はバイト指向の関数なのでこれは 1バイトといってもいい) を*unsigned char として*読み込む」という機能を持ちます. もちろん読み込めなければ EOF を返します. つまり, fgetc は (そして getchar も) 「unsigned char で表される値の範囲に加えて EOF (これは定義により負の数) も返す」ことが考えられ, 当然 char を返すわけにはいきません. そういう事情で「int を返す」ことになっています. と, 規格を読めばわかる. 以下 #3 への突っ込み: 「getcharがマルチバイト文字を受け入れる」としても議論は全く変わりません. また, 「変数の領域の確保」についてもそのようになるとは限りませんし, 「char が 8ビット」であることも規格上保障されません.

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.4

回答が幾つか付いていますが、オマケと思ってください。 先ず、char = 文字、int = 数値 と思っていませんか? よくある間違いなんですが、Cでは両方とも数値です。 違いは精度で、charは8ビット、intは処理系にマッチした精度です。 仮に、getcharがマルチバイト文字を受け入れると、charではダメ ですね。それと、「処理系にマッチした精度」というのはCPUにとり、 最も都合が良い形式という意味でもあります。計算や比較などでは 一時的にint型に変換してから、元の形式に戻すコードが生成される こともあります。 また、変数の領域の確保では境界がこれに合わされます。 例えば、char a, b ; としたら、2バイトの領域を確保したように 感じると思いますが、32ビット機では4バイト境界に位置付けられ るので、メモリは8バイト確保され、先頭にa、+4の所にbが割り 付けられます。残りの3バイトの部分はデッドスペースです。 今時はメモリがフンダンにあるんで、こんな重箱の隅を突くような こと言うと、「貧乏臭い」と笑われますけどね。

回答No.2

getcharの仕様で戻り値がint型だからです…というと身も蓋もないので 参考URLの【getchar()が何故 int型変数で受けるのか】をお読み下さい。 処理系によってはchar型が0~255までの値しか取れないので、EOF(=-1) を認識出来ないということらしいです。

参考URL:
http://www9.plala.or.jp/sgwr-t/c/sec08.html
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

C言語の仕様上、getchar()の戻り値がint型だからです。 >「ch」は「char」でなく「int」型でとるのが良い 取るのがよい、ではなく、取らねばならない、です。

関連するQ&A

  • putchar(getchar())はなぜできない

    途中は省略しますが、 int main(void){ int c; c=getchar(); putchar(c); return 0; } はプログラムとして一文字入力・一文字出力しますが、 すこしプログラムを省略して   c=getchar(); putchar(c); を putchar(gerchar()); とすることは何故できないのか? プログラムの関数と数学の関数は違うという事や、int cでcがchar型でないこと。 これが数学の関数なら引数のない関数は数学にない事。 cは数学でいう代入ではなく、単なる箱で有ること。 getchar()の部分が'A'とかの定数なら領域として確保されているため、 int c; c='A' putchar(c)などせず、putchar('A') とできます。 又、この様な問題がHaskellのモナドに結びついていった。 など何となく分かりますが、いまいちきちんと説明できません。 宜しく願います。

  • getchar関数について

    初歩的なことなのかもしれませんが、お分かりになる方、教えてください。 getchar関数は、 int d; d = getchar(); のようにして使いますよね。 でも、 int c,d; do{  scanf("%d",&c) }while(c!= 0); d = getchar(); のように、getcharの前に繰り返し処理を置くとうまく実行できません。 なぜでしょう? ちなみにソフトはVisual C++6.0をつかってます。 よろしくお願いします。

  • getchar,isalphaについて

    C言語を習いはじめてまもない者です。getcharとisalphaについて教えてください。  まず、getcharから。この関数は、キーボードから文字を一文字ずつ読み、読み出した文字を返す。といった働きをするそうですが、この関数を用いて、取り込んだ文字をなぜか、int型で宣言した変数に代入しています。(例:int aなどのaに取り込んだ文字を代入している。)なぜ、文字を取り込んでいるのに、intで宣言した変数に代入すのでしょうか?charで宣言した変数に代入しなくていいのですか?  次に、isalphaについてです。この関数は、変数に代入されている文字が数字か文字かを判断して、文字が入力されていると、0以外の値を返す関数だそうです。しかし、この関数も、変数の宣言がintです。なぜ、charではなくintで宣言するのでしょうか?

  • getcharの働きについて

     1文字入出力関数getchar()、putchar()の働きを調べるため、次のソースを作って動かしてみました。'>'を使って、実行結果をテキストファイルに出力してみました。 ★ソース1(□はタブ) ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ #include <stdio.h> #include <stdlib.h> int main(void) { □int ch; □printf("何か文字を入力して下さい。\n"); □printf("(Ctrl+Zが入力されたら終了します。)\n"); □while ((ch = getchar()) != EOF) □□putchar(ch); □ □return EXIT_SUCCESS; } ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ ★実行結果 ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ 何か文字を入力して下さい。 (Ctrl+Zが入力されたら終了します。) a abcde ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆  上のように、遊びで文字列を入力してみましたところ、1文字と同様に、入力したとおりに出力されました。そこで、入力したものを確認するために、printf()で出力する行を一つ次のように入れましたところ、次の実行結果のようになりました。 ★ソース2(□はタブ) ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ #include <stdio.h> #include <stdlib.h> int main(void) { □int ch; □printf("何か文字を入力して下さい。\n"); □printf("(Ctrl+Zが入力されたら終了します。)\n"); □while ((ch = getchar()) != EOF) □□printf("入力は%c\n", ch); □□putchar(ch); □ □return EXIT_SUCCESS; } ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ ★実行結果 ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆ 何か文字を入力して下さい。 (Ctrl+Zが入力されたら終了します。) 入力はa 入力は 入力はa 入力はb 入力はc 入力はd 入力はe 入力は  ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆  getchar()で上のように文字列を入力した場合、異常終了にはならないのでしょうか。また、2バイト文字('あ')とか、その文字列("あいうえお")を入力して実行してみましたが、異常にはなりませんでした。getchar()に文字列を入力した場合、どのように処理されるのでしょうか。実用的ではないかもしれませんが、コンピュータの動きをちゃんと理解したいと思いますので、よろしくお願い致します。

  • unsigned int型について

    C言語初心者です。 unsigned int型に関する質問です。 --------------------------------- #include <stdio.h> int main(void) { unsigned int in1 = 10; unsigned int in2 = -10; unsigned char ch1 = 10; unsigned char ch2 = -10; printf("in1 = %d\n", i); printf("in2 = %d\n", i); printf("ch1 = %d\n", ch1); printf("ch2 = %d\n", ch2); return 0; } --------------------------------- 上記のプログラムを作成して実行すると、結果は以下の通りです。 [実行結果] in1 = 10; in2 = -10; ch1 = 10; ch2 = 246; 変数in2の値を表示した結果に関してですが、 unsigned int型にも関わらず負の値「-10」が表示されるのは 何故でしょうか?

  • fflush(stdin)の使い方とprintf()関数getchar()関数の違いについて

    はじめまして。 現在c++を勉強し始めて1週間の初心者です。 fflush(stdin)について質問です。下記のプログラムで小文字入力したアルファベット1文字を大文字に変換して出力しています。方法(1)ではgetchar()関数とputchar()関数を使用していますがどうしてこの場合にはfflush(stdin)が必要となり、方法(2)のprintf()関数とscanf()関数を使用した場合はfflush(stdin)が必要ないのでしょうか?どなたか私のような初心者でも分かるように詳しく説明してもらいたいです。 何故かプログラムを書いているとprintf()とscanf()がよく混乱します。原因として、printf()を先に書く場合と、scanf()を先に書く場合が有るからだと思っているのですが、まだよく理屈の理解ができません。なので出来ればこれらの関数についても基本的な概念を教えていただきたいです。それと方法(2)では何故最後にscanf(%c):が無くても良いのかも良く理解できません。 どなたか是非とも回答宜しくお願いします。 #include <stdio> main void() { 方法(1) printf("\n文字を1つ入力してください:"); fflush(stdin);    char ch=getchar(); ch=ch-32; putchar(ch);    方法(2) printf("\n文字を1つ入力してください:") //fflush(stdin);必要なし???    char ch; scanf("%c",&ch); ch=ch-32; printf("%c",ch);    //scanf(%c):??? }

  • Cのgetcharについて

    Cの文字取得についての質問です。 #include <stdio.h> main() { int a,b,c,d; b=0; printf("1~10の間で数字を入力してください。\n"); scanf("%d",&a); printf("%dで処理します。\nよろしいですか?\nはい:y いいえ:n\n",a); c=getchar(); この場合getcharで文字を取得することができません。 というかenterを押して次に進んだようになってしまいます。ですがc=getchar();を2回繰り返すと文字を取得できます。 1回だと文字取得できなくて2回繰り返すと文字を取得できる理由が知りたいです。 scanfを最初に行っている事が絡んでると思うのですが 具体的な理由を教えてください。

  • 標準関数 getchar( ) の動作について

    getchar()の動作がよくわかりません。 以下のコードでバッファに'\n'が残ってしまっていて?その'\n'が読み込まれている事まで解りました。 どのようにすればキーボードから入力を受け付けるようになりますか? よろしくお願いいたします。 #include <stdio.h> int main(int argc, char *argv[]) {   int iDataA = 0;   int iDataB = 0;   /* キーボードから文字を入力 */   iDataA = getchar();  /* <-- 'a'を入力しエンター */   iDataB = getchar();  /* <-- キーボードからの入力を受け付けません */  return 0; }

  • int型とchar型について

    C言語初心者です。 よろしくお願いします。 ◎1----------------------- #include<stdio.h> int main(void) { int ss[4]="789"; printf("%c\n",ss[0]); return 0; } --------------------------- ◎2----------------------- #include<stdio.h> int main(void) { int *p; p="789"; printf("%c\n",*p); return 0; } --------------------------- ◎1、◎2の2つのプログラムについて疑問があります。 ◎1の「int ss[4]="789";」と◎2の「int *p;」のintの部分は今まで、何の疑問も抱かず、「char」として入力していました。 そこでchar型は1バイトの整数、int型は4バイトの整数ということで容量が違うだけで、intとしても大丈夫だろうと思ったのですが、 ◎1では、「'initializing' : 'char [4]' から 'int [4]' に変換することはできません。」とエラーが出て、◎2では「'char [4]' から 'int *' に変換することはできません。」とエラーが出ます。 intは文字列は扱えないということなのでしょうか? 以上intだと実行できない理由がわかりません。 初歩的なことですいませんが、教えていただけると嬉しいです。

  • strchr() の第2引数はなぜ int 型なのでしょうか

    もしかすると、ちょい前の質問(https://okauth.okwave.jp/qa4151232.html)と同じことを聞いているような気もしますが、気にせずポスト。 その質問を読んだ時に strchr() のマニュアルを見たわけなんですが、そのプロトタイプ宣言は char* strchr(const char* s, int c); なんですね。どうして第 2 引数の型が int なのでしょう?「文字」c を検索するんだから普通に考えれば char ではないかと思うのですが、誰か教えて下さい。 ソースはこんな感じだったので、int である必要はないように思えるのですがどうなんでしょうか? 負数を与えたときに「何らかの動作」を期待してのことなのでしょうか? char* strchr(const char* s, int c) {  char ch;  ch = c; /* <= 結局 char 型にしている */  for ( ; ; ++s) {   if ( *s == ch ) {    return (char*)s;   }   if ( *s == '\0' ) {    return NULL;   }  } }

専門家に質問してみよう