• ベストアンサー

どうすればいいのか教えてください。

下記のようなソースをどうすればうまくできるのでしょうか? flag=1; /*flagはint型で宣言しています*/ while(flag){ printf("0を押してください"); scanf("%d", flag); } 上記で0を入力するとwhile文は抜けられると思いますが、 ここでたとえば「k」などの文字を入力すると 暴走してしまいます。 たとえ文字を入力しても暴走しないようにできないでしょうか?

noname#25605
noname#25605

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

  • ベストアンサー
  • Interest
  • ベストアンサー率31% (207/659)
回答No.1

一つの手としては、 (1)1文字読み込んで、数字の0かどうか判定する。 (2)数字の0でなかったら捨てる。 という方法がありますね。具体的には while(flag){  char c;  printf("0を押してください");  c = getchar();  if( '0' == c ){   flag = 1;  } } これでてきとーなキーを押されても、'0'以外は無視できるはずです。

noname#25605
質問者

お礼

丁寧なご回答ありがとうございます。 このようなときにcが0~9ならflag=1とするにはどうしたらよいのでしょうか?

その他の回答 (8)

  • R32C
  • ベストアンサー率39% (115/290)
回答No.9

>#8様 添削ありがとうございます。 戻り値を設定していませんでしたね。 お返しというのもアレですが、 貴殿の例を添削させていただくと、バッファ不足で、暴走 するケースがあるようですね。 やはり、貴殿を含め皆様のご指摘のように例題と言えどもscanfでは暴走 しないプログラムは、できないようですね。 #8のプログラム cygwinでコンパイルと実行の例 $ ./a 0を押してください yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 3 [main] a 2548 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack) Segmentation fault (core dumped)

回答No.8

おはようございます。 私も、#4さん、5さんが既に書かれてますが、scanf は使うことはお勧め出来ません。 教科書的に、勉強用は別ですがね。getchar か、fgets を使います。 >#7さんへ(悪意はありません) コピペ落ちかもしれませんが、戻り値(return)がないので、 一応(注)コンパイルすれば警告が出ます。動作に問題はありませんが。 一切、警告、エラーの出ない質問者様のソースが暴走していてもね。 以下、ソースと共にコメント内に先に書いてます。 ご参考になれば。 #include <stdio.h> #include <stdlib.h>/*これは atoi の為必要も調べられてからの方が良いでしょう*/ /*読み込み不一致は、scanf を for や while などのループの中で用いた場合、*/ /*入力バッファに残されたデータを永遠に受け付けない為、無限ループになってしまい意外に深刻な問題となります*/ /*全体的なソースの良し悪しは別にしてます*/ /*scanfを使っても、読み込み不一致を回避してます*/ /*k等でも終了します*/ /*Cが出来た頃から使っていたのを思い出しながら*/ /*scanf を使うことを前提に、XP + BCC でテスト*/ /*今後は使用コンパイラ&OSは明記されるのが良いでしょう*/ /*flag と付いた名前の変数は、変数名の性質上 0 か 1 にセットし直して使用します*/ int main(void) { char a[20]; int flag = 1; while(flag != 0){ printf("0を押してください\n"); scanf("%s", a); flag = atoi(a);/*ここの一般ユーティリティ関数部分は、質問者様の最初のソースに近づけいます*/ } return 0; }

noname#25605
質問者

お礼

ご回答ありがとうございます。 是非参考にさせていただきます。

  • R32C
  • ベストアンサー率39% (115/290)
回答No.7

flagがないですが、単に0-9待ちなら 以下のコードでいいのでは? #include <stdio.h> #include <ctype.h> int main(void) { printf("0-9を押してください\n"); while(!isdigit(getchar())); }

noname#25605
質問者

お礼

ご回答ありがとうございます。 是非参考にさせていただきます。

  • Interest
  • ベストアンサー率31% (207/659)
回答No.6

ANo.1 = Interest です。 ごめんなさい、ANo.1 のサンプルソース、間違えていますね。flag = 1 をセットしたってwhileループから抜けれない。 > このようなときにcが0~9ならflag=1とするにはどうしたらよいのでしょうか? getchar() で取得した1文字がASCIIコードで0~9の範囲内かどうか見ればいいですね。具体的には、 #include <stdio.h> int main (){ int flag = 1; while(flag){ char c; printf("0-9を押してください:"); c = getchar(); if( '0' <= c && c <= '9'){ flag = 0; } } return 0; } ここで、'0' はASCIIコードで 0x30、'9'は 0x39 ですから、 if( 0x30 <= c && c <= 0x39 ) と書いても同じことです。 (今回のサンプルコードは、ちゃんと動作を確認しました。)

noname#25605
質問者

お礼

度々の質問へのご回答ありがとうございます。 勉強になりました。

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

がると申します。 なにはともあれ「絶対にscanfは使ってはいけない」です。 おっしゃるとおり、入力わずかでもミスると暴走しますから。 文字を取得するには、#3さんが書かれているgetcharか、或いはfgetsを用いてください(getsはNGです、念のため)。

noname#25605
質問者

お礼

ご回答ありがとうございます。 scanfの恐ろしさがわかりました。これからは注意したいと 思います。

  • Qwerty-36
  • ベストアンサー率25% (58/226)
回答No.4

知らなかった・・・(^^;) http://wisdom.sakura.ne.jp/programming/c/c58.html 普段はscanf()なんて腐った関数、使いませんので・・・(^^;)。 #scanf()なんて、教科書以外で見たことがない。通常は他の回答者の方々同様、文字で受けて、範囲内であることを確認して、数値化します。

参考URL:
http://wisdom.sakura.ne.jp/programming/c/c58.html
noname#25605
質問者

お礼

ご回答ありがとうございます。 scanf()は使わないものなのですね(^^;)

回答No.3

   だいぶ様子が変わるけどこんな方法も、 #include <stdio.h> int main(void) { char flag; do{ printf("0を押してください"); if((flag = getchar()) != '\n') while(getchar() != '\n') ; }while(flag != '0'); return 0; }  

回答No.2

  #include <stdio.h> int main(void) { int flag = 1; while(flag){ char c; printf("0を押してください"); scanf("%c", &c); if(c != '\n') while(getchar() != '\n') ; flag = (c != '0'); } return 0; }  

noname#25605
質問者

お礼

ご回答ありがとうございます。 いろんな手法が知れてよかったです。

関連するQ&A

  • C言語の初歩的な問題です。

    現在C言語の入力の部分を勉強しているのですが 数字の入力をもらってから、それが数字じゃない場合 もう一度入力を受けるようなものを作りたいのですが、 うまく数字なのか文字なのかが判定できなくてこまっています。 どうすればいいのでしょうか? int n; int flag = 0; do{ printf("value:"); scanf("%d",&n); if(入力された値が数字であった場合) { flag = 1; } }while(flag == 0);

  • do while文の条件

    do while文の条件にprintfを使う場合、これはありなんでしょうか? 内容:0が入力されていたら、whileのprintfを実行してからdoに戻る。0以外ならprintfを実行しないで処理を抜ける。 int i; do { printf("0以外の数字を入力してください。\n"); scanf("%d",&i); }while(i == 0 && printf("まじめに入力してください。\n"));

  • 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) 実際には、一文字の制限なく、数字以外の何かを入力したら、再び入力待ちになるプログラムを作りたいのですが、これはどうしたらいいのでしょうか。 つまり 時給: のところに数字以外ならまた 時給: となるようにしたいのです。お願いします。

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

  • n^kのwhile文のプログラムについて

    下のプログラムを実行すると無限に計算されるのはなぜですかどこがおかしいか教えてください /* while1.c---for bun* n no jou*/ main() { int n,k,m,i; printf("Input n\n"); scanf("%D",&n"); printf("Input k\n"); scanf("%d",&k"); m=1; while (i<=5) { m=m*n; printf("%d no %d jou =%D\n",n,i,m); i++; } } あとこれをdo while文にするにはどうすればいいんですか

  • C言語のswitch文について間違っているところを教えてください

    初めに初心者ですので間違っているところは説明つきの回答をしていただければありがたいです。 今回switch文を使って 「足し算、引き算、掛け算、割り算」のプログラムを作ったつもりなのですが、intを使うと割り算の小数点が出ないしfioat文を使うとswitch文には、使えないと出るしどのようにしたら良いのか御回答よろしくお願いします。 (今は、int文でプログラムを作っているつもりです。) #include <stdio.h> void main (void) { int a,b,k; printf("どのような計算をしたいか数字を選んでください。\n"); printf(" 1.足し算 (例 a+b)\n"); printf(" 2.引き算 (例 aーb)\n"); printf(" 3.掛け算 (例 a×b)\n"); printf(" 4.割り算 (例 a÷b)\n"); printf("計算したい番号を入力してください "); scanf("%d",&k); switch (k){ case 1: printf("aを入力してください "); scanf("%d",&a); printf("bを入力してください "); scanf("%d",&b); printf("\n答えは a+b で %d です\n",a+b); break; case 2: printf("aを入力してください "); scanf("%d",&a); printf("bを入力してください "); scanf("%d",&b); printf("\n答えは aーb で %d です\n",a-b); break; case 3: printf("aを入力してください "); scanf("%d",&a); printf("bを入力してください "); scanf("%d",&b); printf("\n答えは a×b で %d です\n",a*b); break; case 4: printf("aを入力してください "); scanf("%d",&a); printf("bを入力してください "); scanf("%d",&b); printf("\n答えは a÷b で %d です\n",a/b); break; default: printf("明記してあるどれかの数字を再入力してください"); } }

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

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

  • printf()で出力したいんですが?

    #include <stdio.h> int main( void ) { int air[4]; int i; i = 0; printf( "データ入力\n" ); do{ scanf( "%d\t", &air[ i++ ]); } while(air[ i - 1 ] > 0 ); printf( "%d\n", i ); return 0; } このプログラムはコンパイル出来ますが、期待していたprintf関数での出力ができません。 その理由として何がありますか?関数の使い方が間違っているのか、DO~WHILE文が使えない場所 なのか、もし直すとすればどう直せばいいのですか。

  • 関数の値(scanf)

    初心者なもので、言葉の使い方を間違っていたら申し訳ありません。いいたいことが伝わればよいのですが…。 scanfに関して疑問に思ったことがあります。経験的なことなので、正しいかわからないです。次の(1)と(2)から(3)のことが正しいか教えてください。 (1) int a; do{ printf("整数を入力してください\n"); }while(scanf("%d",&a) ==0); printf("入力した数は、%dです",a) このとき、「(いかなる整数)+(ENTER)」を入力しても、do~whileのループを抜け出す。 (2)また、上のプログラムで、継続条件式の中身を  … }while(scanf("%d",&a)!=0);  … とすると、「(いかなる整数)+(ENTER)」を入力してもループが抜け出せない。 (3)したがって(1)と(2)から、scanf()は入力するだけで、値を真(1)を返す。

  • 祝日判定です。

    祝日判定 カレンダーですが、エラーが出てしまいます。どうかよろしくお願いいたします。ソースの一部です。 for (j=0; j<6; j++) { for (k=0; k<7; k++) { if (cal[i][j][k]==0) printf(" "); else if(hantei(yy,mm,dd,youbi) == 2){ printf("(%3d) ",cal[i][j][k]); flag = 1; // 日曜と祝日が重なったらflagをたてる } else if(hantei(yy,mm,dd,youbi) == 1 || flag == 1){ printf("(%3d) ",cal[i][j][k]); printf("\t"); flag = 0; } else if((i-1)%7 == 6){ // 土曜日 printf("%3d ",cal[i][j][k]); printf("\t"); } else{ printf("(%3d) ",cal[i][j][k]); //printf("%d"); //日付を出力 flag = 0; } if((i-1)%7 == 6) printf("\n"); //土曜のあとは改行 } int hantei(int yy,int mm,int dd,int youbi){ if((mm==3 && dd== (int)(20.8431 + 0.

専門家に質問してみよう