• ベストアンサー

永久ループ・・・

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

noname#57874
noname#57874

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

  • ベストアンサー
  • natural
  • ベストアンサー率37% (419/1115)
回答No.1

これはscanf()の動作としては仕方のないことなのです。 scanf()は%d指定時に数字以外の入力があると暴走します。 したがって、動作の保障が必要なら何らかの手段を講じてやらなければなりません。 例えば一旦文字列として取り込み、数字以外の文字が混じっていないか判定した後に数値に変換するといった具合です。(isdigit()やatoi()を用いて) #これをscanf()のバグと呼ぶ人もいますが、改修されないところをみると仕様なのでしょうね。

noname#57874
質問者

お礼

悩んでいたのが、情けなるくらい簡単に謎が解けました。^^; 有り難うございました。 しかし、こんな初歩の初歩で躓いてるようでは先が思いやられます・・・

その他の回答 (1)

  • brogie
  • ベストアンサー率33% (131/392)
回答No.2

同じような質問がありますので”scanf”で検索して見て下さい。 少し慣れると、scanfという関数は使わないようです。 参考URLなど参考になるでしょう。 特に、他人に使わせるソフトにはscanfは使用できません。何を入力するか解りませんから、、、 では。

参考URL:
http://oshiete1.goo.ne.jp/kotaeru.php3?q=88787
noname#57874
質問者

お礼

以前に本でscanf関数とgotoはあまり使わない方がいいと書いてありました。scanfは何で使わない方がいいのかさっぱり理解できませんでしたが、これで少しだけ納得! 有り難うございました。

関連するQ&A

  • ループのとめ方

    入力した文字を小文字から大文字に 変えるプログラムで、コントロール+z で、ループを抜け出すようにしたい。 連続して2度コントロール+zを 押さないととまらないのですが、 どのようにすれば、1度コントロール+zを 押すだけで、終了できるのでしょうか? 何かアドバイスをお願いします。 ======================================== #include <stdio.h> #include <ctype.h> #include <string.h> int main(void) { char moji[50],check=0; int i,len; while(check !=EOF){  printf("Enter : ");  check = scanf("%s",moji);  len=strlen(moji);  if(check!=EOF){   printf("Display : ");   for(i=0;i<len;i++){     printf("%c",toupper(moji[i]));   } } } return 0;

  • 【C言語】二重forループ内でscanfを使ってchar型変数に数値(

    【C言語】二重forループ内でscanfを使ってchar型変数に数値(%d)を入力すると、きちんとループ処理されないのはなぜ? プログラムを下に用意しましたのでご覧下さい。 二重forループ内で入力を繰り返すプログラムです。 ついでに i j の値を出力するようにしました。 -----------------プログラム---------------- int main (void){ char input = 0; // 入力値 char型にするとforループでインクリメントエラー(int型にすると問題ない) int i = 0, j = 0; , printf("数値を入力して下さい。('-1' で入力終了)\n"); for( i=0 ; i<3 ; i++ ){ // i がちゃんとインクリメントされない for( j=0 ; j<3 ; j++ ){ scanf("%d", &input); // char 型変数に %d で入力すると、i がきちんとインクリメントされない printf("[i][j] = [%d][%d]\n", i, j); if( input == -1 ){ printf("入力を終了します。\n"); break; } } if( input == -1 ) break; } return 0; } ---------------------------------------- ---------実行結果(入力値はchar型)--------- 数値を入力して下さい。('-1' で入力終了) 1 2 3 4 5 6 7 8 9 [i][j] = [0][0] [i][j] = [0][1] [i][j] = [0][2] [i][j] = [0][0] [i][j] = [0][1] [i][j] = [0][2] [i][j] = [0][0] [i][j] = [0][1] [i][j] = [0][2] -1 [i][j] = [16777215][0] 入力を終了します。 ---------------------------------------- ----------実行結果(入力値はint型)---------- 数値を入力して下さい。('-1' で入力終了) 1 2 3 4 5 6 7 8 9 [i][j] = [0][0] [i][j] = [0][1] [i][j] = [0][2] [i][j] = [1][0] [i][j] = [1][1] [i][j] = [1][2] [i][j] = [2][0] [i][j] = [2][1] [i][j] = [2][2] ---------------------------------------- ご覧の通り、char型変数に値を入力しているために、forループで i がきちんとインクリメントされません。 入力値は -128~127 の値しか想定していないので、メモリの消費を少しでも抑えようと思いchar型で宣言したのですが、思わぬ所でおかしな挙動が起こってしまいました。 int型で宣言すればいいだけなのですが、なぜこんな挙動になるのか知りたいです。 よろしくお願いします。

  • 3つの整数が等しいかどうか調べるプログラム

    3つの整数が等しいかどうか調べるプログラムがよくわからないので、どなたか教えていただけないでしょうか?ちなみに、わからないながらに作ってみました。 #include <stdio.h> int main(void) { int x, y, z; puts("3つの整数を入力してください。"); printf("整数1:"); scanf("%d",&x); printf("整数2:"); scanf("%d",&y); printf("整数3:"); scanf("%d",&z); if (x==y==z) puts("3つの整数の値は同じです。"); else puts("3つの整数の値は違います。"); return (0); }

  • 文字の数値化 関数化

    文字を入力されたとき、数値入力を促す関数を作りたいのですが、 最初の文字が文字ならエラーメッセージがちゃんと出るのですが、 最初の文字が数字ならエラーメッセージが出てくれません。 アドバイスお願いいたします。 tew2 ← エラー出る 2test ← エラー出ない #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> float ss_input(void); int main(){ int i; int pop; printf("何人の入力しますか(3人以内)->"); do{ pop=ss_input(); if(pop >3) printf("3人以内でお願いします\n"); }while(pop<1 || pop>3); return 0; } float ss_input(void){ char p[100]; float st; int i=0; scanf("%s",p); while( p[i] != '\0'){ if(isdigit(p[i])==0){ printf("数値を入力してください->"); scanf("%s",p); continue; } else{ break; } } st=atof(p); return st; }

  • ループが回らない

    #include<stdio.h> #include<string.h> #define HASH_SIZE 100 #define NAME_SIZE 20 char name[ HASH_SIZE ][ NAME_SIZE ]; i int hash_func( char str[] ) { } void main() { char s[ NAME_SIZE ],i; int index ; while(1){ printf("文字を入力!"); scanf("%s",s); if( s[0]='.') break; index = hash_func(s); strcpy( name[ index ],s) ; printf("*\n"); } } このプログラムの 無限ループのところがぜんぜん回らないんです。 自分なりに試行錯誤してみたのですが 限界に達しましたので助言をいただきたいです。 上の関数は今はなにも書いてないですが、 書いてあっても動かないです。 月曜日提出の課題なので なるべく早め回答いただけると幸いです。 アドバイスお待ちしております。

  • 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);

  • scanf関数の戻り値について

    --------------------------------------- #include<stdio.h> int main(void) { int dt; while(scanf("%d",&dt)==1){ if(dt==0){ printf("0は入力しないでください\n"); puts(""); } else if(dt<0){ dt=-dt; printf("入力値の絶対値は「%d」です\n",dt); puts(""); } else{ printf("入力値の絶対値は「%d」です\n",dt); puts(""); } } return 0; } --------------------------------------- 以上のプログラムについて疑問があります。 scanf関数の戻り値が1の間、繰り返すというもので、入力の時に整数入力ですが、あえて実数である1.1を入れたとします。 scanfの戻り値は1で、dtには整数部の1だけ設定されていたので、これでもうまくいくのかと思ったのですが、次の入力はscanfの戻り値が0になっていて出来ませんでした。 何故0になっているのかわかりません。 入力バッファに何か残ってしまっているということなのでしょうか? 以上教えていただけると嬉しいです。

  • for文内でscanf関数により配列に数値を格納することについて

    プログラミング初心者です。 よろしくお願いします。 ◎1------------------------------------ #include<stdio.h> int main(void) { int i,dt[3]; for(i=0;i<3;++i){ printf("dt[0]=%d\n",dt[0]); printf("dt[1]=%d\n",dt[1]); printf("dt[3]=%d\n",dt[3]); scanf("%d",&dt[i]); printf("i=%d\n",i); puts(""); if(dt[i]==0){ break; } } printf("dt[0]=%d\n",dt[0]); printf("dt[1]=%d\n",dt[1]); printf("dt[2]=%d\n",dt[2]); printf("dt[3]=%d\n",dt[3]); printf("i=%d\n",i); puts(""); i=1; while(1){ printf("%d ",i); if(1000<i){ break; } i*=2; } puts(""); return 0; } ---------------------------------------- ◎2------------------------------------ #include<stdio.h> int main(void) { int i,dt[2]; for(i=0;i<3;++i){ printf("dt[0]=%d\n",dt[0]); printf("dt[1]=%d\n",dt[1]); printf("dt[2]=%d\n",dt[2]); scanf("%d",&dt[i]); printf("i=%d\n",i); puts(""); if(dt[i]==0){ break; } } printf("dt[0]=%d\n",dt[0]); printf("dt[1]=%d\n",dt[1]); printf("dt[2]=%d\n",dt[2]); printf("i=%d\n",i); puts(""); i=1; while(1){ printf("%d ",i); if(1000<i){ break; } i*=2; } puts(""); return 0; } ---------------------------------------- 以上2つのプログラムについて疑問があります。 まず◎1については、あえて添え字のdt[3]の値を見てみようと思ったら、iの値が入っているとわかりました。 しかし、何故添え字の番号の配列にiの値が入っているのかがわかりません。 次に◎2ですが、3回目のループで、添え字の番号の配列自身に入力した数値を格納すると、iと添え字番号配列に入力した数値が入っていました。 何故このようになっているのか疑問です。 以上のような疑問があります。 添え字の番号の配列とiが何か関連があるようですがいまいちわかりません。 教えていただけると嬉しいです。

  • 教えてください!!

    文字を入力する。例えば、DFGHJ。次に番号を入力して、その番号に示された値を表示。ここでは、2が入力されれば、Fを表示するのですが、分かりません。 考えてみたのですが、コンパイルエラーで、出来ません。教えてください。宜しくお願いします。 #include <stdio.h> int main(void) { char str[6], no; printf("文字を入力する", str); scanf("%s", str); printf("番号を入力:"); scanf("%d", &no); switch(no,str[]) { case 0 : puts("%d番目は%sです",no, str[0]); break; case 1 : puts("%d番目は%sです",no, str[1]); break; case 2 : puts("%d番目は%sです",no, str[2]); break; case 3 : puts("%d番目は%sです",no, str[3]); break; case 4 : puts("%d番目は%sです",no, str[4]); break; case 5 : puts("%d番目は%sです",no, str[5]); break; } return(0); }

  • ループ

    #include<stdio.h> int main(void) { int i=1,sum=0; int num=1; while(num>0) { printf("整数を入力してください。(マイナスの値で終了)\n"); scanf("%d",&num); printf("%dが入力されました。(%d番目の繰り返しです)\n",num,i); sum+=i; printf("1から%dまでをたすと%dです。\n",i,sum); i++; } printf("繰り返しが終わりました。\n"); printf("加算値は%dです。\n",sum); printf("%d回繰り返しました。\n",i); return 0; } このプログラムで101以上の数値は加算しないようにするにはどうすればいいですか。

専門家に質問してみよう