2010-12-06 5 views
11

Ich sah nie so eine während Anweisung vor.Komma getrennt Ausdruck in While-Schleife in C

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

Ich lese online, dass der Zustand zu kommen, während Schleife ist die ganz rechts [! Feof (stdin)]. Dann, was ist die Verwendung der oben während Aussage im Gegensatz zu

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

Auch während Anweisung einen Ausdruck nimmt, so ist 1,1,1 ein gültiger Ausdruck in C?

Antwort

17

Die beiden angegebenen Schleifen haben nicht die gleiche Bedeutung. Durch Verwendung des Komma-Operators auf diese Weise konnte der Autor einen Code angeben, der bei jeder Iteration ausgeführt werden sollte, auch wenn die Schleife selbst nie eingegeben wurde. Es ist eher wie eine do ... while() Schleife oder so etwas wie die folgenden:

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

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

Die comma operator ist am besten als, na ja, ein Operator. Genau wie + ist ein Operator, so dass 2 + 3 ein Ausdruck ist (was zufällig zu einem Wert von 5 führt), so dass , ein Operator ist und somit 0, 1 ein gültiger Ausdruck ist (was zufällig zu einem Wert von 1 führt, da das der letzte Operand war).

2

Ihre vorgeschlagene Änderung nicht entspricht. Dies ist:

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

Ich würde stattdessen vorschlagen, die Arbeit in eine Funktion abbrechen:

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

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

Ihr zweites Beispiel hat ein anderes Verhalten als das erste, und hat einen Bug.

Wenn die Codezeile:

fgets(str, 100, stdin); 

schlägt fehl, da es sich um eine Lese am Ende der Datei war, dann wird der Rest des Blocks ausgeführt werden.

Im ersten Satz von Code tritt der feof() Test nach dem fgets() auf, der die EOF-Bedingung verursacht, so dass der while()-Block nicht ausgeführt wird.

Da fgets() NULL, wenn es EOF getroffen hat (und alle Daten in den Puffer nicht gelesen hat), könnte ich die Schleife Code wie:

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

    // ... 
} 

die noch etwas anderes Verhalten ist (da sein ein weniger ">" gedruckt). Wenn das wichtig wäre, würde ich eine extra Instanz von printf() vor die Schleife legen.

Im Allgemeinen, da es dazu neigt, Verwirrung zu verursachen, würde ich den Komma-Operator vermeiden, außer dort, wo es wirklich, wirklich benötigt wird oder wo es keine Verwirrung verursacht. Zum Beispiel wird es manchmal in for Loop-Klauseln in einer nicht-verwirrenden Weise verwendet, um zu ermöglichen, dass mehrere Variablen bei jeder Schleifeniteration aktualisiert werden.

+1

die Schleife geschrieben Eigentlich ohne die Verarbeitung der Linie beenden wird 'fgets' beenden von EOF Empfang statt von einem Newline erhalten. Dies führt dazu, dass die Schleife eine letzte Zeile ignoriert, die nicht in einer neuen Zeile endet, was möglicherweise das gewünschte Verhalten ist, aber eher ein Fehler. –

+0

@R .: Ich erinnere mich an die Beobachtung von http://www.drpaulcarter.com/cs/common-cerrerrs.php#4.2: "Der Autor hat noch nicht gesehen, dass ein Schüler die Funktion feof() benutzt korrekt!" –

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

Commas innerhalb einer Weile eher wie dieses Verhalten:

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

while(!feof_wrapper(stdin)) { 
.. 
.. 
} 
Verwandte Themen