getchar()に関する質問

このQ&Aのポイント
  • getchar()について教えてください。
  • visual studio 2010 professionalでgetchar()を使用してキーボード入力を待機させる方法について教えてください。
  • getchar()を1回しか使わないとキーボード入力を待機させることができない理由について教えてください。
回答を見る
  • ベストアンサー

getchar()について 教えてください。

visual studio 2010 professinalで以下のソースをデバッグして ”続行するには何かキーを押してください!”  で待機させたいのですが getchar()一個だけでは実現しません。   2個重ねるとOKです。どうしてでしょうか。  -------------- 以下のようにscanf関数がなければokということは突き止めたのですが、、、。  ご教授ください。 #include <stdio.h> int main(void) { int i; printf("なにか数字を入力してください。\n"); scanf("%d",&i); printf("今あなたが入力した数字は%dです。\n",i); printf("続行するには何かキーを押してください!"); getchar(); //getchar(); return 0; } ---------------------------------------------------------------- int main(void) { printf("続行するには何かキーを押してください!"); getchar();   return 0; }

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

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8517/19361)
回答No.3

>printf("なにか数字を入力してください。\n"); >scanf("%d",&i); この時点で「123」と入力しても、入力が終了しません。入力を終了させるには「Enter」も押さないとなりません。 Enterを押すと入力が終了し、入力した「123[Enter]」がstdin(標準入力)に送られます。 次にscanfの%dにより、stdinから「123」が取り出され、数値に変換された後、iに代入されます。 この時、stdinには「まだ取り出されていない[Enter]」が残ったままになっています。 >printf("今あなたが入力した数字は%dです。\n",i); >printf("続行するには何かキーを押してください!"); この時点でも、まだ[Enter]が残っています。 >getchar(); ここでgetcharを行うと「stdinに、まだ[Enter]が残っている」ので、それが取り出されます。なので、キー入力待ちはしません。 同じプログラムを書き換えて、getchar()を「4つ」にしてから、最初の入力で「123abc[Enter]」と打ってみましょう。すると、getcharでは「キー入力待ち」をしない筈です。 なぜなら、scanfが「123」しか使わずに「abc[Enter]」を残してしまう為、1つ目のgetcharには「a」が、2つ目には「b」が、3つ目には「c」が、4つ目には「[Enter]」が入力されてしまうからです。 scanfを使用したあとにgetcharを使用する場合は、getcharの直前に「[Enter]まで読み捨てる」と言う処理が必要になります。

ninufastar
質問者

お礼

親切、丁寧、細かく、かつ解りやすい説明ありがとうございました。理解できました。

その他の回答 (3)

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

「行単位の入力」で fgets+sscanf というのはよく見るけど, まじめに考えるとこれはこれでとても難しい処理を余儀なくされるんだよね>#1. scanf("%d%*[^\n]\n",&i); で「最初から数字以外の文字を入力したとき」を問題にするだけなら返り値を見ればいい. もっとも, それでも本気でやると int f; while (f = scanf("%d", &i), scanf("%*[^\n]\n"), f == 0) { } のようにやっぱり面倒. これをやってくれるルーチンを作ればいいともいえるが, そういうルーチンを作るなら最後の「数字でない奴ら」を読み捨てない int scanInt(int *p) { int f; while ((f = scanf("%d", p)) == 0) { scanf("%*[^\n]"); } return f; } の方が (より scanf の仕様に近くて) いいような気がする.

ninufastar
質問者

お礼

長文の説明ありがとうございました。ご親切感謝します。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

#1です。 >scanf("%d%*[^\n]\n",&i); これだと、最初から数字以外の文字を入力したときにだめですね・・・すみません。 やはりエラー処理なども含めてちゃんとやりたいのであれば、fgetsで入力して、sscanfで変換するのがよいと思います。

ninufastar
質問者

お礼

ありがとうございました。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.1

はい、scanfが問題です。 行単位の入力であれば、fgets+sscanfを使うほうがよいです。 簡単に対応するなら、 scanf("%d ",&i); と、%dの後ろにスペースを入れてみてください。 ただ、この場合、数値の後ろに余計な文字を入れてしまうとうまくいきません。 scanf("%d%*[^\n]\n",&i); なら大丈夫かな。

関連するQ&A

  • 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を最初に行っている事が絡んでると思うのですが 具体的な理由を教えてください。

  • C言語

    文を繰り返すときに、『続けますか(Y=続行。N=終了)』と表示して、Yが入力されたら文を繰り返すようにしたいのですが、わからないので教えてください。 #include<stdio.h> int main(void) { int m,s,r,num; char moji; num=1; do{ printf("距離を入力してください。\n"); scanf("%d",&m); printf("平均速度を入力してください。\n"); scanf("%d",&s); r=m/s; printf("所要時間は%dです。\n",r); printf("続けますか?(Y=続行。N=終了)\n");/*このあたりがどうすればいいのかわかりません*/ moji=getchar(); }while(num) printf("終了します。\n"); return 0; }

  • scanf関数のプログラムをgetchar関数で

    scanf関数を使って四則演算、論理輪、論理積をint、float、double型で表示するプログラムを作ったのですが これをscanf関数ではなく、getchar関数で組みなおし、関数化する課題が出ました。 そのままscanf関数のところだけを変えても型が違うというエラーが出てうまくいきません。 どうすればいいでしょうか? 一応scanf関数で組んだプログラムの一部を載せておきます。 #include <stdio.h> #include <math.h> main() { float a , b; float x[5]; printf("正の数字を2つ入力して下さい(小数点を含めて4ケタまで):\n"); for(;;) { printf("\na="); scanf("%f" , &a); if(a>=0 && a<=9999 && a) { break; } else { printf("****aに入力エラー****\n"); printf("数字は4ケタ以内の正数を入力:\n"); continue; } } for(;;) { printf("b="); scanf("%f" , &b); if(b>=0 && b<=9999 && b) { break; } else { printf("****bに入力エラー****\n"); printf("数字は4ケタ以内の正数を入力:\n"); continue; } } x[0] = a+b; x[1] = a-b; x[2] = a*b; x[3] = a/b; x[4] = a||b; x[5] = a&&b; printf("\n"); printf("int型 結果:\n足し算=%d\n" , (int)x[0]); printf("引き算=%d\n" , (int)x[1]); printf("掛け算=%d\n" , (int)x[2]); printf("割り算=%d\n" , (int)x[3]); printf("論理和=%d\n" , (int)x[4]); printf("論理積=%d\n" , (int)x[5]); printf("\n"); printf("float型 結果:\n足し算=%f\n" , x[0]); printf("引き算=%f\n" , x[1]); printf("掛け算=%f\n" , x[2]); printf("割り算=%f\n" , x[3]); printf("論理和=%f\n" , x[4]); printf("論理積=%f\n" , x[5]); ・ ・ ・ getchar(); }

  • 警告 W8065について。

    このプログラムを実行したら、実行結果は思い通りになったのですが、 「警告 W8065…プロトタイプのない関数」 と言うのが出ました。  (1)これを消すにはどうすればよいのかを教えてください。  (2)このプログラムはわざと4つに分けているのでこの状態のままプログラムのどこをいじればよいのかを教えてください。 OSはWindows XPでボーランドのコンパイラを使用しています。 #include<stdio.h> int hiki(); int kake(); int waru(); int main(){ int a,b; printf("一つ目の数字\n"); scanf("%d",&a); printf("二つ目の数字\n"); scanf("%d",&b); printf("計%d\n",a+b); hiki(); return 0; } int hiki (){ int c,d; printf("一つ目の数字\n"); scanf("%d",&c); printf("二つ目の数字\n"); scanf("%d",&d); printf("計%d\n",c-d); kake(); return 0; } int kake (){ int e,f; printf("一つ目の数字\n"); scanf("%d",&e); printf("二つ目の数字\n"); scanf("%d",&f); printf("計%d\n",e*f); waru(); return 0; } int waru (){ int g,h; printf("一つ目の数字\n"); scanf("%d",&g); printf("二つ目の数字\n"); scanf("%d",&h); printf("計%d\n",g/h); return 0; }

  • プログラムの添削

    以下のような数当てゲームを作りました.なるべくうまいプログラムを書けるようになりたいのですが,どのような改善点がありますか?よろしくお願いします. /*数当てゲームを作りなさい.*/ #include<stdio.h> void maegaki(void); /*このように関数を定義しまくることに意味はあるのか?main関数はすっきりするけど.*/ void in_check_out(int i); int main(void) { int i; int j; maegaki(); for(j=0;j<10;j++) { scanf("%d",&i); in_check_out(i); if(!(i-1)) return 0; printf("残り%d回です.\n",9-j); } return 0; } void maegaki(void) { printf("数当てゲームをはじめます.\nぼくの好きな整数を当ててください.\nチャンスは10回です.\nヒントはボゾン\n"); } void in_check_out(int i) { if(!(i-1)) { printf("正解!答えは1です.\n"); } else { printf("残念!\n"); if(i>1) printf("%dより小さいです.\n",i); else printf("%dより大きいです.\n",i); } }

  • for文

    for文なのですが、 scanfで得た、 iを for文のi--で、一づつへらしてますが、 0でfor文がおわりますが 0で終わりの記述がない気がするんですが、 どうしてでしょか? int main(void) {    int i;    printf("正の整数を入力してください。\n");    scanf("%d",&i);    for( ; i ; i--)    printf("qが入力されました。\n");    return 0; }

  • scanf()関数の使い方について

    はじめまして。 質問があります。 まずは、以下のコードを見てください。 ---------------------------------------------------------------- #include<stdio.h> int main(void) { char c; int i; printf("0を入力すると終了します。\n"); while(1) { printf("文字を入力してください=>"); scanf("%c",&c); printf("入力した文字は %c です。\n",c); printf("数字を入力してください=>"); scanf("%d",&i); if(i==0) { break; } printf("入力した数字は %d です。\n",i); } return 0; } ---------------------------------------------------------------- 上のコードを実行すると、初回はscanf()はcharとintの両方とも 入力待ちになってくれるのですが、2回目以降はcharは入力待ちに なってくれません。これは、なぜなのでしょうか? ご教授お願いします。 現在VC++6.0を使用しております。

  • 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()に文字列を入力した場合、どのように処理されるのでしょうか。実用的ではないかもしれませんが、コンピュータの動きをちゃんと理解したいと思いますので、よろしくお願い致します。

  • 素数判定の繰返し

    繰返し素数判定を行ない、CtrlーDで終了するプログラムをつくっています。 まず繰返しなしの素数判定プログラムを作り #include<stdio.h> int main(void) { int a,i; printf("自然数を入力:"); scanf("%d",&a); if(a<=0) printf("入力エラーです。\n"); else if(a==1) printf("1は素数ではない。\n"); else{ for(i=2; i*i<=a; i++){ if(a%i==0) break; } if(i*i>a) printf("%dは素数です。\n",a); else printf("%dは素数ではない。\n",a); } return(0); } これはちゃんとできたのですがそれを繰り返すことができません。 #include<stdio.h> int main(void) { int a,i; printf("自然数を入力:"); scanf("%d",&a); while((a=getchar())!=EOF){ if(a<=0) printf("入力エラーです。\n"); else if(a==1) printf("1は素数ではない。\n"); else{ for(i=2; i*i<=a; i++){ if(a%i==0) break; } if(i*i>a) printf("%dは素数です。\n",a); else printf("%dは素数ではない。\n",a); } printf("自然数を入力:"); scanf("%d",&a); } printf("プログラムを終了します。\n"); return(0); } これは訳わからないことになっちゃいます。。。 どうしたらいいんでしょうか??

  • cプログラム

    #include<stdio.h> /*Calc MAX of (a,b)*/ int max(int x,int y) { if(x>y) return x; else return y; } /*Calc n!*/ void fact(int n) { int i,ans; ans=1; for(i=n;i>=1;i--){ ans*=i; } printf("ans=%d\n",ans); } /*END*/ void end() { printf("Thanks\n"); exit(0); } /*Main*/ int main() { int key; int a,b,saidai; int n; while(1){ puts("\n=====Main MENU ====="); puts("1.......max(a,b)"); puts("2.......n!"); puts("9.......END\n"); printf("Input No(1,2,9)=?"); scanf("%d",&key); switch(key){ case 1: printf("Inputs:a,b?"); scanf("%d,%d",&a,&b); saidai=max(a,b); //Call max(a,b) printf("max(%d,%d)=%d\n",a,b,saidai); break; case 2: printf("Input:n?"); scanf("%d",&n); fact(n); break; case 9: end(); break; default: printf("!!!!!Miss Input_No!!!!!\n"); break; } } のプログラムなのですが、1の処理を行った場合max(a,b)の値が正しく表示されません どこを直せばいいでしょうか? return(0);

専門家に質問してみよう