• ベストアンサー

fgetsなどのときのstdinのバッファを消すには?

こんにちは,今C(C++でない)を使用しています。 たとえば, char str[20] fgets(str,sizeof(str),stdin) としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。 C++などでは fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。 よろしくお願いします。

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

  • ベストアンサー
  • Fooky
  • ベストアンサー率71% (59/82)
回答No.4

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ. 末尾に'\n'が出るまで掃出せばいいんですよね. fgets(str, sizeof(str), stdin); if ( str[strlen(str)-1] != '\n' ){ while( getchar() != '\n' ); } でいいんだ.失礼しました.

yu393939
質問者

補足

ありがとうございます。かなりのヒントになりました。 お礼のついでに完成したのを載せておきます。 #include <stdio.h> #include <string.h> int main() { char str[20]; int chk_digit; while(1) { chk_digit=0; puts("入力"); fgets(str, sizeof(str), stdin); if ( str[strlen(str)-1] != '\n' ) { while( getchar() != '\n' ); chk_digit=1; } if (chk_digit == 1 || str[0] == '\n' ) { break; } } printf("出力:%s\n",str); return 0; }

その他の回答 (3)

  • Fooky
  • ベストアンサー率71% (59/82)
回答No.3

システムは何ですか?fseek(stdin, 0, SEEK_END, 0)はLinuxでは効かないという話を読んだことがあります.SEEK_ENDをEOFと考えれば当然ですが.fseekでいけるシステムではSEEK_ENDを現状でのバッファエンドと捉えているんでしょうか. で,おおがかりになってきますが,pollまたはselectを使って全部掃出すのはどうでしょう? #include <stdio.h> #include <sys/poll.h> int main(int argc, char **argv) { char s[11], ss[11]; struct pollfd fdlst = {0, POLLIN, 0}; int l; l = read(0, s, 10); /* sに文字列読込み*/ s[l] = 0; /* 掃出し */ do { fdlst.revents = 0; poll( &fdlst, 1, 1 ); } while ( (fdlst.revents&POLLIN) != 0 && read(0,s,10) > 0 ); /* ssに文字列読込み*/ l = read(0, ss, 10); ss[l] = 0; printf("%s", ss); } こうするとうちでは,sに何文字打とうと,それ以降に打った文字がssに入りました.ただし,pollはファイルポインタ(stdin)ではなくファイルディスクリプタ(0 = stdin)を使うので,読込みもそれに合わせてreadなどのシステムコールでやる必要があるようです. #しかし私はfflush(stdin)に驚きでした.それでいけるシステムもあるんですね.

参考URL:
http://www.linux.or.jp/JM/html/LDP_man-pages/man2/poll.2.html
yu393939
質問者

お礼

早速のお答えありがとうございます。 ただ,これを私のPCでコンパイルしようとすると, (#include <unistd.h>を加えて・・) [XXXXXXXX]$ gcc -g -Wall -o test test.c [XXXXXXXX]$ ./test abcdefghijk      (←1回目に打った内容) abcdefghijk      (←2回目に打った内容) abcdefghij[XXXXXXXXX]$ k -bash: k: command not found [XXXXXXXX]$ となり,1回目の入力は11文字以上がうけつけなく,サイドの入力の際は10文字だけが出力され後の一文字(k)がこのプログラムが終了したシステムのコマンドとして認識されるようになりました。 どうしたらいいでしょうか。

noname#4252
noname#4252
回答No.2

fseek(stdin, 0, SEEK_END); 試してませんが。 他には、バッファが空になるまで読み捨てるとか。

yu393939
質問者

お礼

こんにちわ, それも,fssekも無理だったんですよ。 char str[20]; fseek(stdin, 0, SEEK_END); if ((*fgets(sk,sizeof(sk),stdin) < 0x21) || strlen(sk) >= 21 ) { puts("error"); goto start1; } のようにしたんですけど,むりでした。

  • 100Gold
  • ベストアンサー率27% (284/1018)
回答No.1

fflushはCの標準関数のはずです。 上手く行かないのには別の原因があるのではないでしょうか?

yu393939
質問者

お礼

いや,ANSI C規格では、 「fflush関数は出力ストリーム(stdoutとかstderr)にしか使えないように定義されている」 参照:http://www.peke.jp/archive/fmc/article/dev/dev001b.html らしいんですよ。ですから, fflush(stdout) はできても, fflush(stdin) はできないみたいなんです。

関連するQ&A