3

Beej のIPCガイドをチェックしていたところ、1 行のコードが気になりました。

特定のページの while ループにspeak.cは、チェックする 2 つの条件がありwhile (gets(s), !feof(stdin))ます。

したがって、私の質問は、ほとんどの場合、1 つの条件のみをテストしているときに見たように、これがどのように可能であるかということです。

PS:私はこれらに少し慣れていません。どんな助けにも感謝します。ありがとう!

4

4 に答える 4

6

スニペット

while (gets(s), !feof(stdin))

コンマ演算子を使用し、最初に を実行しgets(s)、次に条件の結果である をテスト!feof(stdin)します。

ちなみにgets は使用しないでください。非常に安全ではありません。それを使用している情報源には注意してください。おそらく、言語を学習するための良い情報源ではありません.

コード

while(gets(s), !feof(stdin)) {
    /* loop body */
}

と同等です

gets(s);
while(!feof(stdin)) {
    /* loop body */
    gets(s);
}

getsループの前とループ本体での繰り返しを避けるため、より簡潔になります。

于 2012-05-02T15:02:07.320 に答える
3

何人かの人々が、これに関するいくつかの問題をすでに指摘しています。私は確かに、gets(まったく)を使用することはお粗末な考えであることに同意します.

ただし、もう1つの詳細について言及する価値があると思います。これはfeof(file)ループを終了する条件として使用されるため、ファイルの終了前にエラーが発生した場合にも誤動作する可能性があります。エ無限ループに陥ります。

ジョブを実行する正しい方法は でfgets、その戻り値を確認します。

while (fgets(s, length_of_s, stdin))
    process(s);

fgets これは、ファイルからの読み取りに成功したかどうかをテストするため、ファイルの終わりまたはエラーのいずれかでループを終了します。

もう 1 つの細かい点:fgets文字列を読み取るとき、通常は改行を行末に保持getsします (どこで破棄するか)。存在する場合は、おそらくもう少しコードを追加して削除する必要があります(改行が存在しない場合は、割り当てたバッファーよりも長い行を処理する可能性があります)。

于 2012-05-02T15:23:41.673 に答える
2

この構文は、2 つの式を評価しません。最初に を実行してから、関数呼び出しによって変更される可能性があるものをgets(s)評価します。!feof(stdin)gets()

どちらも を使用しているため、これはあまり良い方法gets()ではありません。これは安全な関数ではなく、初心者にとっては読みにくいものです (したがって、質問です)。

于 2012-05-02T15:05:17.433 に答える
2

このテストはカンマ演算子を使用しておりgets(s)!feof(stdin).

于 2012-05-02T15:04:43.407 に答える