• ベストアンサー

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

  • C言語でscanfを用いた入力

    C言語でscanfの動作を確かめる為に、次のプログラムを作成して実行してみました。 #include <stdio.h> int main(void){ int i; printf("Input1:"); scanf("%d",&i); printf("Input2:"); scanf("%d",&i); printf("Output:%d",i); return 0; } このプログラムは1回目と2回目に数値を入力すると正常に出力します。 例 1回目の入力に10、2回目の入力に20を入力した時の出力結果 Input1:10 Input2:20 Output:20 今度は1回目で数値、2回目で文字を入力してみました。 そしたら2回目の入力が無視されました。 例 1回目の入力に10、2回目の入力にAを入力した時の出力結果 Input1:10 Input2:A Output:10 今度は1回目で文字を入力してみました。 そしたら2回目の入力は要求せず、いきなりよく分からない数値が出力されました。 例 1回目でAを入力した時の出力結果 Input1:A Input2:Output:-858993460 どうして文字を入力したら正常に出力しなくなるのでしょうか?

  • C言語(while構文)

    #include<stdio.h> #include<conio.h> void main() { int i=1,sum=0; char c='m'; while(c!='e')//eでない限りwhileループを実行する { sum=sum+i; printf("\n1 kara %d madewo tasuto %d desu.\n",i,sum); i++; printf("nanikakeywo oshitekudasai.owaru tokiha 'e'\n"); c=getch(); } printf("loopwo nukemashita\n"); getch(); } getch()の代わりに、scanf()を使って整数値を入力させ、負の数が入力されたら終了するプログラム(正を入力したら「次の数値を入力せよ」とだして、繰り返す。)を造りたいのですが、どこを変えればよいか教えてください。

  • C言語のプログラムみてください(isdigit)

    質問は2つあります。 (1) scanf関数を使って、 時給: と表示されたところに一文字打ち込み、数字以外ならばもう一度 時給: と表示されるプログラムを作りたいです。 以下のプログラムなら、 isdigit関数は数字を渡せば0以外の数を返す(真)から、 while文の条件式(偽)のようにすれば、 ・数字を一文字うちこめばwhile文の条件式にあてはまらない、すなわち下のプログラムではisdigit(payment) != 0 となり、return 0; が実行され、プログラムが終わる ・数字以外を一文字打ち込めばwhile文の条件式が真となり、printf関数とscanf関数が実行されて入力待ち状態になる と思ったのですが、どうやら違うようです。実際には ・数字一文字打てばまた入力待ちになる ・数字以外を一文字打てば永遠にprintf関数とscanf関数が実行される のはなぜでしょうか。 #include <stdio.h> #include <ctype.h> int main(void){ int payment; do{ printf("時給[円]:"); scanf("%d",&payment); } while (isdigit(payment) ==0) ; return 0; } (2) 実際には、一文字の制限なく、数字以外の何かを入力したら、再び入力待ちになるプログラムを作りたいのですが、これはどうしたらいいのでしょうか。 つまり 時給: のところに数字以外ならまた 時給: となるようにしたいのです。お願いします。

  • Cプログラミング(文字入力)

    文字を二つ入力して、TかFであれば 1~3、それ以外は4を返すプログラムです。 下記のソースでは正常に動作しませんでした。 どの文法が間違っているか判らないので、 どなたか指摘頂けないでしょうか。 宜しくお願いします。 char a,b; printf("1つめの文字を入力してください-->"); scanf("%c",&a); printf("2つめの文字を入力してください-->"); scanf("%c",&b); if(a=='T'&&b=='T')   printf("結果:1\n"); else if((a=='T'&&b=='F')||(a=='F'&&b=='T'))   printf("結果:2\n"); else if(a=='F'&&b=='F')   printf("結果:3\n"); else   printf("結果:4\n");

  • C言語の無効な値が入力されたときの繰り返しについて

    C言語で最初に入力した整数の5倍になるまで何度も入力を促すプログラムでわからないところがあるのですが #include  "stdio.h" int main() { int a ; do { printf("input a:"); scanf("%d",&a); } while( )     ← printf( ) ←この二つの()内の文字をどうすればよいのか分かりません return 0; } 教えていただけないでしょうか

  • while文のデータの終わり

    C言語なんですが 購入合計金額を求めるプログラムで、 1回のプログラム実行で、続けて何回でも計算を行い、 えんぴつの購入数に999を入力すると計算を終了するようなプログラムを作りたいのですが、 #include <stdio.h> main() { int a,b,c,goukei; a=b=c=0; while(a!=999){ printf("商品をいくつ買いますか??\n"); printf("えんぴつ   = "); scanf("%d",&a); printf("消しゴム   = "); scanf("%d",&b); printf("ボールペン = "); scanf("%d",&c); goukei=a*100+b*150+c*200; printf("合計購入価格は%d円です\n\n",goukei); } } 上のようなソースを作ったのですが えんぴつのところに999を入力してもプログラムが終了せずに続いてしまいます… 試行錯誤してもうまくいきません。 どこが間違っているのでしょうか?

  • C言語で 小文字を大文字に変えるプログラム

    C言語で小文字を大文字に変えるプログラムを造ったのですが、エラーが出てしまいます。 どこが間違っているのか教えてください。 #include<stdio.h> main() { char a[100]; scanf(%c,&a[i]); int i=0; while(i<100){ i++; if(a[i]>60){ printf("%x-20",a[i]); }else{ printf("%x",a[i]) } } }

  • c言語のプログラムについて

    今年からC言語を始めた大学1年生です。レポートで四則計算を行うプログラムを6/19までに作らないといけないです。使えるのは今までに習った選択型、反復型、関数scanfです。このプログラムの留意点は次の4つです。 1.使う演算を選択してもらう   例えば   どんな演算をしますか? 1:+,2:-,3:*,4:/ (選択) 2.演算を行う数値を入力してもらう   例えば   a + b の計算をします。aを入力してください。 3.演算結果を表示する   ○+○の答えは ○です 4.計算終了か、それともほかの演算を行うか 決める   0:計算終了 1:他の計算を行う を選択してください  以下のプログラムはこのことを留意してプログラムをつくりました。どこがおかしいのでしょうか。 #include<stdio.h> main() { short a,b,m,n; long c,d,e,f; c = a + b; d = a - b; e = a * b; f = a / b; m = 1; printf("整数を入力してください:"); scanf("%d",&a); printf("どんな演算をしますか?:"); printf("1: +,2: -,3: ×,4: ÷ :"); scanf("%d",&n); while(m=1){ if(n<=4){ while(m=1){ switch (n<=4){ case 1: printf("整数を入力してください:"); scanf("%d",&b); printf("%d + %d = %d \n",a,b,c); break; case 2: printf("整数を入力してください:"); scanf("%d",&b); printf("%d - %d = %d \n",a,b,d); break; case 3: printf("整数を入力してください:"); scanf("%d",&b); printf("%d × %d = %d \n",a,b,e); break; case 4: printf("整数を入力してください:"); scanf("%d",&b); printf("%d ÷ %d = %d \n",a,b,f); break; } } } else { printf("計算できません。"); printf("演算をやり直してください。\n:"); } } printf("計算を終了しますか、それとも他の計算を行いますか?:"); printf("0:計算終了,1:他の計算を行う:"); scanf("%d",&m); printf("計算を終了します。\n"); } 提出期限があるのでなるべく早めのご回答待ってます。生意気言ってすいません。

  • while文について、c言語です。

    ぼくはプログラム始めたばかりです。ミスを見つけられた方、ご指導お願いします。 正整数nを入力して、nの階乗をもとめるプログラムを作りたいのですが、実行結果がいつも1になります。どこがおかしいか教えてください。以下のプログラムです。 #include <stdio.h> int main(void) { int i, n, s; printf("n = ?"); scanf("%lf", &n); s = 1; i = 1; while(i <= n) { s = s * i; i = i + 1; } printf("s = %3d\n", s); return 0; }

  • C言語について

    「キーボードから10個の実数を入力し、それらの平均を求めるプログラムを作れ。」という問題で私は、 #include <stdio.h> void main(void) { float A; float a,b,c,d,e,f,g,h,i,j; printf("実数を入力してください:"); scanf("%f",&a); scanf("%f",&b); scanf("%f",&c); scanf("%f",&d); scanf("%f",&e); scanf("%f",&f); scanf("%f",&g); scanf("%f",&h); scanf("%f",&i); scanf("%f",&j); A=(a+b+c+d+e+f+g+h+i+j)/10; printf("平均は%fです.\n",A); } と考えたのですが、もっとすっきりとしたプログラムはないのでしょうか?もっとシンプルにしたいのです。教えて下さい。よろしくお願いします。

専門家に質問してみよう