• ベストアンサー

C言語 While文(ループ)内の文字入力

While文で、1文字入力をやれば思うようにうまくいかない。数字(データ)入力や、文字列入力の場合(%d 及び %s)ならうまくいく。文面で説明するより実際のプログラムを見た方が分かりやすいと思うので、以下にプログラムとその実行結果、実行結果に対する私が意図している結果とを示します。 【プログラム部分】 #include<stdio.h> int main(void) {    char a;    while(1)    {    printf("1文字を入力:");    scanf("%c",&a);    if(a == 'x')      break;    printf("入力したのは %c です。\n",a);    }    return 0; } 【実行結果(キーボードからは「 e 」と入力」)】 1文字を入力:e 入力したのは e です。 1文字を入力:入力したのは です。 1文字を入力: 【私が意図している結果】 1文字を入力:e 入力したのは e です。 1文字を入力:  ちなみにC言語の環境は、インターネットで無料で入手できる試食版です。(LSI C-86 Ver3.30c 試食版)  上記プログラムを見てもらえればお分かりだと思いますが、「xを入力するまで、永遠と1文字入力とその表示を行う」ことを意図しています。しかし実際の結果は意図に反しています。  1回目は正常に動作しているようですが、問題は2回目以降。scnafで入力待ちをすることなく、なぜかscanfをスルーする形で3回目のscanf入力待ちとなっています。この理由を教えてください。お願いします。

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

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

>1文字を入力:入力したのは >です。 は、[Enter]キーの入力によるためです。 [Enter]キーをスルーする必要があります。    char a; char dummy; /*[Enter]キー用*/    while(1)    {    printf("1文字を入力:");    scanf("%c",&a); scanf("%c",&dummy); /*[Enter]キー用*/    if(a == 'x')      break;    printf("入力したのは %c です。\n",a);    } で、どうでしょうか?

gh8050ke600
質問者

お礼

バッチリ解決しました。有難う御座いました。

その他の回答 (4)

  • ency
  • ベストアンサー率39% (93/238)
回答No.5

入力ストリームに改行文字が残っていることが原因なのは、すでに何名かの方が回答されているとおりです。 scanf() は、空白文字、改行文字、タブ文字といった文字の食べ残してしまうんです。 scanf() の代わりに fgets() + sscanf() なんかを使うのがポピュラーだと思いますが、食べ残しを避けるだけなら、こんな方法もありますよ。 修正前: scanf( "%c", &a ); 修正後: scanf( "%c%*c", a ); "%*c" の部分が、普段は食べ残す改行文字をうまく吸い上げてくれます。 # …とつい最近も同じようなことを書いた記憶があるなぁ。 # http://oshiete1.goo.ne.jp/kotaeru.php3?q=1807169 あたりで。。。

gh8050ke600
質問者

お礼

回答有難う御座います。参考にさせていただこうと思います。

回答No.4

#include<stdio.h> int main(void) { char a[100]; while(1) { printf("1文字を入力:"); scanf("%s",a); if(a[0] == 'x') { break; } printf("入力したのは %s です。\n",a); } return 0; } 例えばこんな感じで直ると思います。 http://homepage1.nifty.com/toshio-k/prog/c/string.html に細かい解説が書いています。 注意すべき点は char a[100];です。 scanf("%s",a);はaのアドレスを先頭から順番に文字列を入力するという意味です。 char a;ですと、アドレスが先頭分(a[0]の分)しかないので、2文字目が入るとどんな動作をするか分かりません。 char a[100];ですと、アドレスa[0]を先頭に、100文字入れる事が出来ます。 他の方も言っているように、2文字目に何かが入っているんだと思います。 printf,scanfはめったに使わないので詳しくは分かりませんが、char型、文字列を扱うのには注意が必要なようです。

gh8050ke600
質問者

お礼

回答有難う御座います。

回答No.3

細かい話はがるさんがなさってますので、 自分からはそのプログラムの動作について。 scanf("%c",&a); で値を取った場合・・例の通り、eを入力したとしましょう。 その場合、入力の方法は「eを居れてエンターを押す」事になるかと思います。 すると、プログラムとしては「e」と「エンター(改行)」を受け取る事になり、 結果として「eを受け取って表示」と「エンター(改行)を受け取って表示」が行われます。 対処法としてはがるさんの提示している方法と、 あまりお薦め出来ませんがrewind(stdin)等をscanf()の前に置く方法もあります。

gh8050ke600
質問者

お礼

回答有難う御座います。

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。 えっと…ものすごく直線ですが。scanfが悪さをしています。っていうか、scanfは、少なくとも人間からの入力を期待するシーンでは「何があろうとも絶対に使っちゃいけない」関数です。 直接的な原因は、入力されたバッファに対してscanfがくい散らかしを残しているので、その残ったデータを次のscanfが拾って奇妙な動作をして…という感じの動きです。 1文字だけを取りたいならgetchar、改行コードまでを取り込みたいならfgetsをつかうようにするとよいかと思います。

gh8050ke600
質問者

お礼

回答有難う御座います。

関連するQ&A

専門家に質問してみよう