1

次の方法を使用して、入力バッファをクリアします。

void dump_line(FILE *fp) {
    int ch;    
    while ( (ch = fgetc(fp)) != EOF && ch != '\n');
}

scanf()を使用してstdinから読み取る場合、これは正常に機能します。

char string[51];
...
scanf("%50[^\n]", string);
dump_line(stdin);

ただし、次のコードのように、代わりにfgets()を使用する場合:

char string[52];
...
fgets(string, 52, stdin);
dump_line(stdin);

// Since fgets() reads in the '\n', trim the end of the string:
string[strlen(string)-1] = 0;

fgets()は'\ n'文字を読み取るため、バッファを1文字大きく割り当て、文字列を1文字戻す必要があることがわかりました。これは正常に機能しますが、dump_line関数に問題があります。scanf()バージョンを使用する場合、[^ \ n]を使用するため、入力バッファーには常に'\ n'が残るため、期待どおりに機能します。したがって、それがバッファに残っている唯一の文字である場合でも、dump_line()でfgetc()は文字を読み取り、それが'\ n'であるため、whileループが壊れています。

fgets()バージョンでは、文字列バッファに収まる場合は'\ n'が読み込まれ、stdinは空のままになります。これにより、プログラムはfgetc()を待機し、ユーザーがEnterキーを押してさらに進む必要がありますが、これは明らかに私が求めているものではありません。一方、ユーザーがバッファに対して長すぎる文字列を入力した場合、dump_line()は正常に機能しています。

問題はEOFに関係していると思いますが、これを意図したとおりに機能させることができないようです。どんな助けでも大歓迎です。

私が取り組んでいるプラットフォームがMacOSXであることが助けになる場合は、これがプラットフォーム固有の癖のようなものである場合に備えて。

4

2 に答える 2

5

バッファをクリアする必要があるかどうかを確認し、

fgets(string, 52, stdin);
size_t len = strlen(string);
if (string[len-1] == '\n') {
    // read in whole line, no need to clear buffer
    string[len-1] = 0;
} else {
    // junk left in buffer, clear it
    dump_line(stdin);
}
于 2013-01-17T16:56:58.177 に答える
1

ungetc改行をストリームに戻すために使用できます。

于 2013-01-17T16:55:43.520 に答える