2010-12-06 11 views
11

前にこのようなステートメントを見たことはありません。Cでwhileループでコンマ区切り式

while(printf("> "), fgets(str, 100, stdin), !feof(stdin)) { 
.. 
.. 
} 

whileループから出る条件が右端[!feof(stdin)]であることをオンラインで読みました。

また
while(!feof(stdin)) 
{ 
     printf("> "); 
     fgets(str, 100, stdin); 
     ... 
     ... 
} 

とは対照的に、文は式を取りながら 次に、上記ながら、文の使用は1,1,1がCで有効な式ですので、何ですか?

答えて

17

与えられた2つのループは同じ意味を持ちません。このようにコンマ演算子を使用することで、ループ自体が決して入力されなくても、すべての繰り返しを実行するコードを指定することができました。

printf("> "); 
fgets(str, 100, stdin); 
while(!feof(stdin)) { 
    .. 
    .. 

    printf("> "); 
    fgets(str, 100, stdin); 
} 
4

comma operatorは、同様に、オペレータとして最もよく考えられます。 +が演算子なので、2 + 3は式(5という結果になる)なので、,も演算子なので、0, 1は有効な式です(結果として値は1になります)それは最後のオペランドだったからです)。

2

あなたの提案変更は等価ではない:それは、より多くのdo ... while()ループ、または以下のようなもののようです。これは、次のとおりです。

while (1) { 
    printf("> "); 
    fgets(str, 100, stdin); 
    if (feof(stdin)) { break; } 
    ... 
    ... 
} 

私が代わりに関数に作業を切り離すことをお勧め:

int get_input(char* buffer, int size) { 
    printf("> "); 
    fgets(buffer, size, stdin); 
    return !feof(stdin); 
} 

while (get_input(str, 100)) { 
    ... 
    ... 
} 
2

あなたの2番目の例では、最初とは異なる振る舞いを持ち、バグがあります。

コードの行の場合:

fgets(str, 100, stdin); 

は、それがファイルの終わりで読み取ったので、ブロックの残りの部分は実行されません。

fgets()の後にfeof()テストが発生し、EOF条件が発生するため、while()ブロックは実行されません。

がEOFを(及びバッファに任意のデータを読み取るいない)ヒットした場合、私は、ループをコードかもしれ戻りNULL fgets()ので(が存在するであろう

依然として若干異なる挙動である
while (fgets(str, 100, stdin)) { 
    printf("> "); 

    // ... 
} 

1つ少ない ">"が印刷されます)。それが重要だった場合は、その前にループの前にprintf()という追加のインスタンスを追加します。

一般に、混乱を招く傾向があるため、実際に必要な場所や混乱を起こさない場所以外はコンマ演算子を避けます。例えば、それは時々forのループ節で使われていて、各ループの繰り返しでいくつかの変数を更新できるようにしています。一方、内部

+1

実際には、書かれたようにループラインを処理せずに終了する 'fgets'改行を受けるからEOF受信の代わりに終了します。これは、改行で終わらない最終行をループが無視するようにします。これは望ましい動作かもしれませんが、バグかもしれません。 –

+0

@R:http://www.drpaulcarter.com/cs/common-c-errors.php#4.2からの観察を思い出しています。「著者はまだどの学生もfeof()関数を使用していない正しく! " –

1
while(printf("> "), fgets(str, 100, stdin), !feof(stdin)) { 
.. 
.. 
} 

カンマがよりこのように振る舞う:

int feof_wrapper(FILE * stream) 
{ 
    printf("> "); 
    fgets(str, 100, stream); 
    return feof(stream); 
} 

while(!feof_wrapper(stdin)) { 
.. 
.. 
} 
関連する問題