• 締切済み

エラーのチェックについて

1~10の数字以外が出たら、再入力を促すようにしたいのですが、上手くいかないので教えてください。 int main(void) { char buf[MAX], moji[MAX]; int n, num; printf("1から10の番号を入力してください:"); while (1) { fgets(buf, MAX, stdin); // 文字列の読み込み n = sscanf(buf, "%d%s", &num, moji); // 文字列から変換 if (num >= 1 && num <= 10 && n == 1) { // 範囲外のエラーチェック break; // 正なら終了 } else { // 間違っていたら入力し直し printf("1から10の番号を入力してください:"); } } 以上のようにして、aや11, ctrlキー+zを入力してEnterを押したときは良いのですが、aの後に続けてctrlキー+zを入力してEnterを押したらelseのprintfがずっと出力され続けてしまいます。それ以外に自分で試した入力の中にはエラーは出ませんでした。ctrlキー+zのことを良く理解していないということもあるのかもしれません。

みんなの回答

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

#include <stdio.h> #define MAX 16 int main(void){ char buf[MAX], moji[MAX]; char stdinBUFF[BUFSIZ]; int n, num; setbuf(stdin, NULL);//バッファリングを止める do { printf("1から10の番号を入力してください:"); if (fgets(buf, MAX, stdin) == NULL) { clearerr(stdin);//EOF クリア continue; } n = sscanf(buf, "%d%s", &num, moji); if (n<0){ fgets(buf, MAX, stdin);//ゴミ漁り continue; } if (num >= 1 && num <= 10 && n == 1) { break; } }while(1); printf("num:%d\n",num); setbuf(stdin, stdinBUFF);//バッファリングを戻す return 0; }

  • mac_res
  • ベストアンサー率36% (568/1571)
回答No.2

Ctrl-Zは、Linux, unix系のshellではサスペンドシグナルに、DOS/Windows系ではEOFとして使われます。 システム依存ですがEOFを入力するとclearerr()でクリアするまで次の入力を受け付けなくなりその現象が起きます。 -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- #include <stdio.h> #define MAX 1024 int main(void) { char buf[MAX], moji[MAX]; int n, num; printf("1から10の番号を入力してください:"); while (1) { if (fgets(buf, MAX, stdin) == 0) { clearerr(stdin); } n = sscanf(buf, "%d%s", &num, moji); if (num >= 1 && num <= 10 && n == 1) { break; } else { printf("1から10の番号を入力してください:"); } } return 0; }

revolution_2005
質問者

お礼

回答有難う御座います。 早速試してみたのですが、適当に文字を入力→続けてctrl-zを入力(abc^zみたいな感じです)→Enterとするとやはりelseのprint文の永続処理になってしまいます。

  • suzukika
  • ベストアンサー率28% (8/28)
回答No.1

こんばんは ロジックはあまりよろしくないので、 σ(^_^)アタシなら簡単に書くと: 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define MAX 10 5 6 int main(void) 7 { 8 char buf[MAX], moji[MAX]; 9 int n, num; 10 printf("Input numbers from 1 to 10:"); 11 while(fgets(buf, MAX, stdin)) 12 { 13 n = atoi(buf); 14 if(n >= 1 && n <=10) 15 { 16 printf("OK\n"); 17 break; 18 } 19 else 20 { 21 printf("Please input number again:"); 22 continue; 23 } 24 } 25 return 0; 26 } となります。 c++なら別の手もありますけどね。

revolution_2005
質問者

お礼

回答有難う御座います。 これだと、ctrl-zを押すと終了してしまいますよね?終了しないで、尚且つ永続処理をなくしたいのですが・・・。

関連するQ&A

  • 何処が間違っていますか?

    ---------------------------------------------------------------------------------------- #include<stdio.h> #include<stdlib.h> #define MAX_LINE 128 int main(void); int main(void) { char buf[MAX_LINE]; int n; printf("降水確率を入力してください。\n"); gets(buf); n = atoi(buf); printf("降水確率は %d %% です。\n",n); if (n >= 50) { printf("傘を忘れずにね。\n"); } else { printf(傘はいりません。\n"); } printf("いってらっしゃい。\n"); return(0); }

  • 空白を含んだ文字列がうまく格納(表示)できない

    こんにちわ。 空白(スペース)の入った文字列の格納(表示)について質問させてください。 以下のプログラムを実行すると、空白の含む文字列がうまく表示されません。 例えば、 in the worldと入力しても、inしか格納されていないみたいです。それはなぜでしょうか? また、どうすればそれを格納、表示させることができるのでしょうか?教えてください。よろしくお願いいたします。 #include <stdio.h> #include <string.h> main() { char buf[BUFSIZ]; char moji[31]; int i; printf("Input string: "); fgets(buf, sizeof(buf), stdin); moji[31] = '?0'; sscanf(buf, "%s", moji); i = 0; while (moji[i] != '?0') { printf("%c",moji[i]); i = i + 1; } printf("?n"); printf("%d letters?n", i); } 【実行例】 csx01:~> gcc prog.c csx01:~> a.out Input string: in the world in 2 letters

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

    typedef struct{ int num; char basic_gainen[MAX][32]; int particle[MAX]; }Gainen; int main (void){ Gainen g1, g2; char str1[256] = "外国_の_大型_の_船"; char str2[256] = "大型_の_船"; char buf[256]; divide(&g1, str1);//文字列の中から助詞と名詞を取得 divide(&g2,str2);//文字列の中から助詞と名詞を取得 printf("gainen:%s\n",print(&g1,buf)); printf("gainen:%s\n",print(&g2,buf)); if(hikaku(&g1,&g2)==1) printf("一部の単語は一致する\n"); } //二つの文字列を比較し、一部一致するかどうかの判定 int hikaku(Gainen *g1, Gainen *g2){ int n,i; if(g1->num != g2->num){ if(g1->num >= g2->num) n = g2->num; else n = g1->num; printf("n:%d\n",n); for(i=n;i>0;i--){ printf("inside loop i:%d\n",i); if(g1->particle[n] != g2->particle[n]) return 0; else if(strcmp(g1->basic_gainen[n],g2->basic_gainen[n]) != 0 ) return 0; } } return 1; } divide関数を省略させて頂きます。 hikaku関数のところで、二つの文字列の助詞と名詞が一致しなかったら0を返すその以外は1と返すというふうにしたいですが、実行したらhikaku関数から0の値wが返された。ループの数を表示したら、上のやり方でループがまわらないというのはわかったんです。上の条件判断はいけないですか?ご教授よろしくお願いします。

  • C言語での文字列ソート動作について

    任意の文字列を入力し、その文字列を昇順にソートするプログラムを作ったのですが、入力する文字の文字数が大きく異なると期待した結果が得られません。 文字数が少なくなったり、他の配列の文字が混ざったりと言う結果に成ってしまっています。 何が原因か分からない状態です。 以下にサンプルを記載させて頂きますので、助言よろしくお願いします。 /*----------------------------------------- 入力例 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC BBBBBBBBBBBBBBBB AAAAAA -----------------------------------------*/ #include <stdio.h> #include <string.h> #include <stdlib.h> void swapc(char *cx , char *cy){ char tmp[100]; strcpy(tmp, cx); strcpy(cx, cy); strcpy(cy, tmp); } int main(){ char *num[100]; char str_tmp[100]; //文字列一時格納 int moji_cnt; //入力した文字列のカウント int n , m; // 文字列入力処理開始 printf("文字列を入力してください\n"); for( moji_cnt = 0 ; moji_cnt != 3 ; moji_cnt++){ scanf("%s", str_tmp); *(num+moji_cnt) = (char *)malloc(sizeof(char) * (strlen(str_tmp)+1)); //メモリ確保 strcpy(*(num+moji_cnt), str_tmp); } puts("\n"); // 文字数ソート処理 for(n = 0 ; n < moji_cnt-1 ; n++){ for(m = 1 ; m < moji_cnt-n ; m++){ if(strcmp(*(num+n) , *(num+n+m)) > 0){ swapc(*(num+n) , *(num+n+m)); // 文字列入れ替え } } } puts("\n"); for(n = 0;n != moji_cnt;n++){ printf("%s\n" , *(num+n)); } free(num); }

  • Run-Time Check Failure #3 と表示されてしまうことについて

    初歩的な質問で申し訳ありません。 Visual Studio C++にて、入力された値を基に最短(最小値)を求めていくプログラムを作成しているのですが、 ”Run-Time Check Failure #3 - The variable 'x' is being used   without being defined.” と表示されて、コマンドプロンプトが実行されません。 なぜこうなってしまうのですか? 参考までに下記に作成したソースコードを示します。 初心者ゆえ書き方がしっかりとできておらず、大変わかりにくいソースかとは思いますが、助言をいただければ幸いです。 #include "stdafx.h" #include "stdlib.h" #define MAX_LINE 256 #define MIN_DATA 3 int _tmain(int argc, _TCHAR* argv[]) { char buf[MAX_LINE]; int i,x,y,z,min_data; int data[MIN_DATA] = {x,y,z}; printf("Sからaまでの距離を入力して下しい。\n"); gets(buf); /*キーボードから値を入力*/ x = atoi(buf); printf("a=%dです。\n",x); printf("Sからbまでの距離を入力して下しい。\n"); gets(buf);/*キーボードから値を入力*/ y = atoi(buf); printf("b=%dです。\n",y); printf("Sからcまでの距離を入力して下しい。\n"); gets(buf);/*キーボードから値を入力*/ z = atoi(buf); printf("c=%dです。\n",z); printf("並べ替えると\n"); min_data = data[30];/*入力された値を降順で並べ最小値を表示*/ for (i = 0; i < MIN_DATA; i++) { if (min_data > data[i]) { min_data = data[i]; } } printf("最短は %d\n", min_data); printf("Enterで終了"); return (0); }

  • javaのコンパイルができません。

    コンパイルができません エラーの内容とソースコードは次です Microsoft Windows [Version 6.0.6002] Copyright (c) 2006 Microsoft Corporation. All rights reserved. C:\Users\j1409061\Documents\java\MeikaiJava>javac SR091409061.java SR091409061.java:7: 式の開始が不正です。 const int MAX_INT = 2147483647; ^ SR091409061.java:8: 式の開始が不正です。 const int BUFFER_SIZE = 100; ^ SR091409061.java:9: ';' がありません。 int main();{ ^ SR091409061.java:16: ']' がありません。 char buf[BUFFER_SIZE]; ^ SR091409061.java:16: 式の開始が不正です。 char buf[BUFFER_SIZE]; ^ SR091409061.java:22: 式の開始が不正です。 n = sscanf(buf, "%d %c", &data, &c); ^ SR091409061.java:22: 式の開始が不正です。 n = sscanf(buf, "%d %c", &data, &c); ^ SR091409061.java:73: 式の開始が不正です。 n = sscanf(buf+i, "%d", &data); ^ SR091409061.java:96: class、interface、または enum がありません。 } ^ エラー 9 個 C:\Users\j1409061\Documents\java\MeikaiJava> //最大値と最小値を求めよう // C:\Users\j1409061\Documents\java\MeikaiJava\SR091409061.java class SR091409061 { public static void main(String args[]) { Scanner stdIn = new Scanner(System.in); const int MAX_INT = 2147483647; const int BUFFER_SIZE = 100; int main();{ /* 変数を定義、初期化 */ int data; int max = -1; int min = MAX_INT; bool data_exist = false; int i, n; char buf[BUFFER_SIZE]; printf("Please input data : "); while(true) { /* データ(1行分読み込み) */ fgets(buf, BUFFER_SIZE, stdin); /* データ取り出しと計算 */ n = sscanf(buf, "%d %c", &data, &c); if( ( n == -1 ) || ( n == 0 ) ) { break; } else if (n == 1) { // the number of data is 1. data_exist = true; data = abs( data ); if(max < data){ /* maxを変更 */ max = data; } if(min > data){ /* minを変更 */ min = data; } } else if (n == 2) { // the number of data is larger than 2. i = 0; while (true) { data_exist = true; data = abs( data ); if(max < data){ /* maxを変更 */ max = data; } if(min > data){ /* minを変更 */ min = data; } // 空白文字を読み飛ばす while (true) { if(buf[i] == ' ') { i++; } else { break; } } // 数字(0から9)を読み飛ばす while (true) { if( ( buf[i] >= '0' ) && ( buf[i] <= '9' ) ) { i++; } else { break; } } // 行末なら終える if(buf[i] == '\n') { break; } // データ読み込み.読み込みに成功したら次の文字へ(i++), 失敗したら終える(break). n = sscanf(buf+i, "%d", &data); if(n == 0) { break; } i++; } } if(n == 0) { break; } } /* 最大値, 最小値を出力 */ if (!data_exist) { printf("No data.\n"); } else { printf("Max = %d\n",max); printf("Min = %d\n",min); } return 0; } } } } よろしくお願いします

  • 数字を当てさせるゲームについて

    #include<stdio.h> #include<time.h> #include<stdlib.h> int main(void) { int limit=0; int no; /*当てさせる値*/ int num; /*入力する値*/ int max=9; srand(time(NULL)); no=rand()%1000; do{ printf("あと%d回入力できます。数字を入力してください。\n",max-limit); scanf("%d",&num); limit++; if(num>no) { printf("大きいです。\n"); } else if(num<no) { printf("小さいです。\n"); } }while(num!=no || limit<max) if(num==no) { printf("正解です。"); printf("%d回で当たりました。",limit); } else { printf("残念ながら不正解です。") } return 0; } これは、0以上999以下の整数を入力させて9回以内にランダムで 入力した値を当てさせるゲームです。 質問内容としては 当てさせる数字を「0以上999以下の数字」→「0以上999以下の3の倍数」に変更するにはどうすればよいかです。 よろしくお願いいたします。

  • C言語 文字列の比較 compare

    プログラミング初心者です。 60文字以内の文字列を入力して、 大小関係を比較・表示するプログラムなのですが・・ 「AはBより大きい」という結果しか出ません。 どこが間違っているのか、ご指摘お願いしますっ。 #include<stdio.h> int main(void) { char moji1[61]; char moji2[61]; printf("文字列Aを入力===>"); scanf("%60s" ,&moji1); printf("文字列Bを入力===>"); scanf("%60s" ,&moji2); if(moji1-moji2>0){ printf("===AはBより大きい===\n"); } else if(moji1-moji2<0){ printf("===AはBより小さい===\n"); } else if(moji1-moji2==0){ printf("===AとBは等しい===\n"); } return 0; } int compare(char *x, char*y) { while(*x==*y){ if(*x=='\0') return 0; x++; y++; } return (*x-*y); }

  • scanf()関数の使い方について

    はじめまして。 質問があります。 以下のコードを見てください。 ---------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> int main(void) { int i; char buf[256]; int y; int m; int d; printf("文字列を入力してください:"); scanf("%s",buf); i = sscanf(buf,"%d/%d/%d",&y,&m,&d); //OK #if 0 i = sscanf(buf,"%d %d %d",&y,&m,&d); //NG #endif printf("日付 %d-%d-%d 戻り値i=%d\n",y,m,d,i); return EXIT_SUCCESS; } ---------------------------------------------------------------- 標準入力から日付を表す文字列「例:"2007/04/17"」を入力してbufに 格納したものをsscanf関数の第1引数に指定して、y,m,dを表示 させてみると、「i = sscanf(buf,"%d/%d/%d",&y,&m,&d)」では、 うまくyとmとdに日付が格納される(つまり、yに2007が入り、mには 04が入り、dには17が入る。)のですが、 「i = sscanf(buf,"%d %d %d",&y,&m,&d);」でbufに格納すると、 yにはうまく格納されるのですが、他のmとdには、うまく格納してくれ ません。これは、なぜなのでしょうか? ご教授お願いします。

  • C言語 strlen 再入力を促す

    文字列の比較で、 文字列の長さが60以上の時、再入力を促します。 while文を使って書いてみたのですが、 文字列Bの入力の前に、もう一度意味もなく 「文字列Aを入力===>」が表示されたり。 文字列Aのほうが小さいのに「Aのほうが大きい」と 表示されるようになったり、変な感じです。 どなたかご指摘・ご指導のほどよろしくお願いします。 int main(void) { char moji1[100]; char moji2[100]; while(strlen(moji1)>60){     printf("文字列Aを入力===>"); scanf("%80s" ,moji1); } while(strlen(moji2)>60){     printf("文字列Bを入力===>"); scanf("%80s" ,moji2);    } if(compare(moji1,moji2)>0){ printf("===AはBより大きい===\n"); } else if(compare(moji1, moji2)<0){ printf("===AはBより小さい===\n"); } else if(compare(moji1, moji2)==0){ printf("===AとBは等しい===\n"); } return 0; } int compare(char *x, char*y) { while(*x==*y && *x!=0){ x++; y++; } return (*x-*y); }

専門家に質問してみよう