この人頭いいなと思ったエピソード

こんにちは,今C(C++でない)を使用しています。
たとえば,
char str[20]
fgets(str,sizeof(str),stdin)
としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。

C++などでは
fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。

よろしくお願いします。

A 回答 (4件)

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ.


末尾に'\n'が出るまで掃出せばいいんですよね.

fgets(str, sizeof(str), stdin);
if ( str[strlen(str)-1] != '\n' ){
while( getchar() != '\n' );
}

でいいんだ.失礼しました.

この回答への補足

ありがとうございます。かなりのヒントになりました。
お礼のついでに完成したのを載せておきます。
#include <stdio.h>
#include <string.h>

int main()
{
char str[20];
intchk_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;
}

補足日時:2003/05/16 15:01
    • good
    • 6

システムは何ですか?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/man …
    • good
    • 0
この回答へのお礼

早速のお答えありがとうございます。
ただ,これを私の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)がこのプログラムが終了したシステムのコマンドとして認識されるようになりました。
どうしたらいいでしょうか。

お礼日時:2003/05/16 13:57

fseek(stdin, 0, SEEK_END);


試してませんが。
他には、バッファが空になるまで読み捨てるとか。
    • good
    • 0
この回答へのお礼

こんにちわ,
それも,fssekも無理だったんですよ。

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

お礼日時:2003/05/16 13:05

fflushはCの標準関数のはずです。


上手く行かないのには別の原因があるのではないでしょうか?
    • good
    • 0
この回答へのお礼

いや,ANSI C規格では、

「fflush関数は出力ストリーム(stdoutとかstderr)にしか使えないように定義されている」
参照:http://www.peke.jp/archive/fmc/article/dev/dev00 …

らしいんですよ。ですから,
fflush(stdout)
はできても,
fflush(stdin)
はできないみたいなんです。

お礼日時:2003/05/16 11:47

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報

このQ&Aを見た人がよく見るQ&A