• 締切済み

ループ中でのscanfおよびcin

あまりに基礎的な質問ですが,ループ中の入力関数が期待する動作になりません. コードを載せます while (1) { int key; scanf("%d", &key); if (key == 1) break; } 期待する動作は1が入力されるまでループし続けるというものですが scanfは一度しか実行されずループし続けます,cinに変えても同様でした 何が原因か分かる方,ご教示ください

みんなの回答

  • chie65535
  • ベストアンサー率43% (8519/19365)
回答No.4

http://www9.plala.or.jp/sgwr-t/c/sec05.html の「5-4.scanf()の注意事項」を読みましょう。 >scanfは一度しか実行されずループし続けます いいえ。scanfは実行されています。 「2度目以降のscanfを呼んだ時、入力バッファに変な物(%dとして受け付けない物)があると、scanfは入力バッファをそのままにして、何もしないで戻ってくる」ので「まるでscanfが実行されていないように見える」だけです。 scanfは「変換できた個数を返す」と言う仕様になっているので while (1) { int key; if (feof(stdin)) break; //EOFの時は終了 if (scanf("%d", &key) != 1) { //予期しない入力なら scanf("%*[^\n]%*c"); //改行も含めて読み飛ばす } else { //変換できたなら if (key == 1) break; //1なら終了 } } など、scanfの戻り値を確認すると良いでしょう。 よく「scanfは、初心者が絶対に使ってはいけない関数」などと暴言を吐く人が居ますが、そんな事はありません。 ・scanfの戻り値をちゃんと確認すれば予期せぬ入力の判定は可能 ・予期せぬ入力を読み飛ばす方法があるので、ちゃんと読み飛ばす の2つをしっかり行えば、初心者でもちゃんと使える関数です。と言うか、変換の便利さ、書式の豊富さから言えば「超初心者向けの関数」です。 「scanfを使わずに、色々とゴチャゴチャ小細工する」って方が、よっぽど「上級者にしか出来ない高等テクニック」です。

  • notnot
  • ベストアンサー率47% (4847/10260)
回答No.3

scanfは、初心者が絶対に使ってはいけない関数です。(中上級者も使い道無いですけど) (1) fgetsとsscanfを組み合わせて使う (2) sscanfの戻り値を確認する char line[1000]; while(1){ int key; if(!fgets(line,sizeof line,stdin)) break; if(sscanf(line,"%d",&key)==1 && key==1) break; } もし、例題にscanf関数が出てくる入門書をお使いなら、別の本を探しましょう。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

このやり方だと、scanfは整数値として解釈できる入力がないと、何度でも再試行してしまいます。 期待した入力が得られなかった場合、行末まで読み飛ばす処理を入れるべきです。 なお、stdinのような入力ストリームに対してfflushを呼び出すと未定義の動作になりますので、やってはいけません。

参考URL:
http://www.kijineko.co.jp/tech/superstitions/fflush-with-input-stream.html
  • aigaion
  • ベストアンサー率47% (287/608)
回答No.1

次の1行をscanfの次の行に追加したらいけるんじゃ? fflush(stdin); 標準入力(stdin)のバッファを吐き出せということです。 入力というのはすぐにプログラムに渡されるわけではなく一定量が溜まってから渡されます。 これを一定量たまるまで待つのではなくすぐに渡せというのが上の意味です。

関連するQ&A

  • C++:cinが上手く使えない

     そもそもcinについてあまり詳しい事は知らないのですが よろしくおねがいします。  cinを使って整数を取りこもうとする時、数字以外が 入ってしまうとおかしな動作をします。  例えば「10未満の整数値を取りこむまで続くループ」で 入力部分を作ろうとした時に、 while(1){  cout << "入力してください" << endl;  cin >> int_a;  if(int_a < 10) break; } 大体 以上の様に書くと、入力する時にアルファベットが 入ってしまうと 入力して下さい 入力して下さい …(エンドレス)… 入力して下さい となってしまいます。cinをあきらめてscanfにしてみると 今度は実行時エラーがでてしまいます。  整数を入力する事が出来て、なおかつアルファベットが 入力されても' 'で囲った値が入るようにするには どのようにすればよいでしょうか?

  • ループを途中で抜けたいのですが。

    無限ループさせているwhileやfor文などで、 何かのキーを押すとループを抜けるように設定したいのですが可能でしょうか? (scanfやcinなどをループの中に組み込まずに。ctrl+Cも無しで。) (あと、フォーム上ではなくコンソール上で。) 多分説明不足なのでもうちょっと詳しく。 たとえば、 while ( i != 1 ){ j += 1; } の様な無限ループを設定したとして、 本来なら if (j > 100 ){ break; } とか、 while文の中に scanf ( "%d" , &i ); 等を入れて終了条件を満たさせるべきですが、 そうではなく、ひたすら無限ループを続けているところにEscキーを押すとループから脱出するようなプログラムを作ってみたいのです。 そういうプログラムは可能でしょうか? どうかご教授下さい。 使用コンパイラ:Visual C++ 2008 Express Edition

  • 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を使用しております。

  • scanf関数について

    こんなプログラムがありました。 char str[80]; while(scanf("%s",str)>=1){    ・・・  } このwhileループは何が入力されたときに終了するのですか?scanf関数は入力された文字を返り値に持つとわかったので、改行コードを入力しましたが、終了しませんでした。どうすればよいのでしょう。よろしくお願いいたします。

  • scanfが実行されません

    Cについて質問です。 whileループに入る前にscanfでchar変数に文字を代入するようにして、その文字でwhileループの条件を設定したのですが、scanfが実行されずにすっ飛ばされてwhileループに入ってしまいます。 同じようなコードををdo-while文で書いてみたところ、一回目のscanfがやはりすっ飛ばされて二回目に入り、そこでscanfが実行されます。 エラーは出ません。何が間違っているのか、さっぱり分かりません。教えてください。

  • 永久ループ・・・

    どうも、最近C言語の勉強を始めた超初心者です。 int main(void) { int i; for(;;){ printf("桁数を入力してください。:"); scanf("%d",&i); if(i<=12) break; else puts("もう一度入力してください。"); continue; } return(0); } 上のソース、i<=12の条件を満たさなければループを繰り返すというプログラムなんですけど、数値を入力した場合は思った通りに挙動するのですが、文字や文字列を入力すると永久ループになります。scanf関数で返値を受け取って判定するなどいろいろ試したのですが、どうしても永久ループになってしまいます。 どうしてか教えてください。お願いします。

  • scanf関数について

    scanfで数字を入力し「CTRL+D」で入力終了となるプログラムを考えています. 調べてみると以下の様なプログラムでは入力終了となります. #include <stdio.h> int main(void) { int a[256]; int i = 0; while(1) { printf("Input%d = ", i); if ( scanf("%d", &a[i]) == EOF || i > 255) { break; } i++; } return 0; } しかし,次の様にすると「CTRL+D」では終了しません. #include <stdio.h> int main(void) { int a[256]; int i = 0; while(1) { printf("Input%d = ", i);   scanf("%d", &a[i]); <-----追加 if ( a[i] == EOF || i > 255) {   <-----変更 break; } i++; } return 0; } この場合は,環境がUNIXのため「-1」と入力すると終了します. 2種類の違いが分かりません. 教えてもらえないでしょうか?

  • scanf関数のループについて

    ソースコード---------------------------- #include<stdio.h> int main(){ int i; while(scanf("%d", &i) != 1){;} return(0); } -------------------------------------- 1が入力されるまで入力待ちになるようなプログラムを意図してるのですが、 このプログラムでは二回目以降の入力ができなくなってしまいます。 なぜでしょうか。 意図したようにプログラムが動作するにはどのように書き換えればよいのでしょうか。

  • whileとscanfの関係について

    while文中のscanf関数が意図しない動作をして困っています 簡略化したコードがこちらになります while(1){ // view printf("view\n"); // input char key; scanf("%c", &key); // update printf("update\n"); } 行いたい動作というのは単純で view -> input -> update ->を繰り返したいだけなのですが 上記プログラムでは下記のような動作になってしまいます view -> input -> update -> view -> update -> view -> input -> 偶数回目のループでは、inputが飛ばされてしまうのですが、何が原因なのかかがわかりません。 言語仕様に詳しい方、どなたかご教示ください。 環境 WindowsXP Visual C++ 2008 ExpressEdition

  • scanf関数のループについて

    ソースコード---------------------------- #include<stdio.h> int main(){ char c; while(scanf("%c", &c) != 1){;} return(0); } -------------------------------------- 入力された文字数が1文字でない間入力待ちになるようなプログラムを意図しているのですが、 例えばaと打ってもaaと打ってもプログラムが終了してしまいます。 意図したようにプログラムが動作するにはどのように書き換えればよいのでしょうか。

専門家に質問してみよう