趣味でプログラミングをしております。
環境は、以下です。
Windows10
Mingw-w64
gcc version 5.2.0 (Rev4, Built by MSYS2 project)
https://oshiete.goo.ne.jp/qa/9287118.htmlの回答2にて、
3つの数字を入力し、数字でない場合は再入力を促すプログラムを提示しました。
これについて、他の回答者様より「fflush(stdin); は一般にはやっていけない操作」との回答をいただきました。
私の環境では、fflush(stdin)を使用しないと以下の様に1回目に誤ったデータを入力すると、再入力時のメッセージが2回繰り返し表示されます。
(推測ですが、windowsで改行コードが2Byteであることから発生しているのではと考えています)
fflush(stdin)を使用しないで、この問題を回避する適切な方法がありましたらご教示ください。
よろしくお願いします。
----------実行結果(fflush(stdin)を使用しない場合)
$ ./a.exe
重複しない3つの数字:abc
重複しない3つの数字:重複しない3つの数字:abc
重複しない3つの数字:重複しない3つの数字:
----------
----------ソース
#include <ctype.h>
#define BUF_SIZE 3 // 3文字
int main(void){
char buf[BUF_SIZE + 1];
int user;
while(1){
fflush(stdin);
printf("重複しない3つの数字:");
fflush(stdout);
fgets(buf, BUF_SIZE + 1, stdin);
if(!isdigit(buf[0])) continue; // 1文字目が数字かチェック
if(!isdigit(buf[1])) continue; // 2文字目が数字かチェック
if(!isdigit(buf[2])) continue; // 3文字目が数字かチェック
break;
}
user = atoi(buf);
printf("number : %d", user);
return 0;
}
----------
No.1ベストアンサー
- 回答日時:
>他の回答者様より「fflush(stdin); は一般にはやっていけない操作」との回答をいただきました。
規格にstdinに対して実施した場合の動作が明記されていないから。
だったかと。
実装依存する。ということです。
>推測ですが、windowsで改行コードが2Byteであることから発生しているのではと考えています
ライブラリー依存でしょうかね。
¥rと¥nの両方をfgets()が改行として処理したのかも知れません。
gccだし。
>fflush(stdin)を使用しないで、この問題を回避する適切な方法がありましたらご教示ください。
読み込み用のバッファをもう少し大きく用意する。でしょうか。
1回目、"abc"を読み込みます。
第2引数で指定した3バイトに達したため。
stdinのバッファには¥rと¥nが残ってます。
2回目、¥rを読み込みます。
fgets()の仕様により改行コードに到達したため。
1回目の読み込みで残るのに注意です。
# 2回目で¥rだけなのか¥r¥nなのか、はたまた¥r¥nが¥nに変換されるのか…はfgets()の後で内容確認してください。
ご回答ありがとうございました。
> 読み込み用のバッファをもう少し大きく用意する。でしょうか。
BUF_SIZEを3から4以上に変更することで発生しなくなりました。
fgetsの直後に配列bufの内容を表示させていたところ以下の様になりました。
----------
fgets(buf, BUF_SIZE + 1, stdin);
for(i = 0; i < BUF_SIZE + 1; i++) printf("%d : %02x\n", i, buf[i]);
----------
\r(0x0a)が入力バッファに残っていたことが原因だった様です。
\r\nが併せて配列buf上の\0になると思っていたのですが、\rは単独で配列に読み込まれてしまうのですね、勉強になりました。
実行結果
----------BUF_SIZE 3(問題発生)
$ ./a.exe
重複しない3つの数字:abc
0 : 61
1 : 62
2 : 63
3 : 00
重複しない3つの数字:0 : 0a
1 : 00
2 : 63
3 : 00
----------
----------BUF_SIZE 4(正常)
$ ./a.exe
重複しない3つの数字:abc
0 : 61
1 : 62
2 : 63
3 : 0a
4 : 00
重複しない3つの数字:
----------
----------BUF_SIZE 5(正常)
$ ./a.exe
重複しない3つの数字:abc
0 : 61
1 : 62
2 : 63
3 : 0a
4 : 00
5 : 00
重複しない3つの数字:
----------
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# プログラミングの問題です。至急教えてください。 /***から***/の部分をプログラミングにしてほし 1 2022/10/13 11:48
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- Excel(エクセル) エクセル関数の変わった使い方 3 2022/05/13 17:12
- その他(プログラミング・Web制作) Pythonを用いたフラッシュ暗算ソフトの開発に必要なもの 2 2023/01/29 02:22
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
*をユーザーが入力した数字の数...
-
正負を反転させて出力するプロ...
-
scanf関数について
-
C言語(構造体)
-
数字以外が入力されたらエラー...
-
Java 6人分の得点を入力し、平...
-
4桁の数字以外を入力したらエラ...
-
Eclipseコンソール表示を、リセ...
-
IF文で戻ることはできますか?...
-
VB.NETで16進数+16進数や16進...
-
if文の条件にscanf関数を使うと…?
-
java初心者です。入力されたの...
-
cout関数を使っているのですが...
-
scanfが2回使えない・・・?;
-
プログラミング初心者です。 Py...
-
scanf()で、エラー対応
-
C言語で入力がないと1をだし続...
-
C言語 逆ピラミッドの作り方
-
入力エラーの処理について。
-
コマンドプロンプトからのEOFの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
*をユーザーが入力した数字の数...
-
正負を反転させて出力するプロ...
-
数字以外が入力されたらエラー...
-
プログラミング初心者です。 Py...
-
double型が正常に認識されてい...
-
java初心者です。入力されたの...
-
Eclipseコンソール表示を、リセ...
-
scanfが2回使えない・・・?;
-
C言語scanf_sで何故か2回入力に...
-
if文の条件にscanf関数を使うと…?
-
プログラミングの問題です 「金...
-
Linuxで入力待ちなしkeyread関...
-
ワードで文字を入力する時の変...
-
cout関数を使っているのですが...
-
batプログラム上で文字列を入力...
-
Userformの入力順序をタブオー...
-
scanf が無視されます
-
C言語 逆ピラミッドの作り方
-
gets_sがうまく動かない
-
Excel VBAで、Application.Inpu...
おすすめ情報