Svaret på dette er, at fflush(stream)
kun er formelt defineret for output streams, så fflush(stdout)
er OK, men fflush(stdin)
er ikke.
Sigtet med fflush(stream)
er at få operativsystemet til at skylle eventuelle buffere til den underliggende fil. Som eksempel på en legitim anvendelse kan nævnes, at studerende ofte har problemer som “min prompt vises ikke!”, hvis de gør noget som:
printf("Enter a number: ");
Men de finder ud af, at dette fungerer fint:
printf("Enter a number:\n");
Selvfølgelig vil de ikke have en newline efter deres prompt, så de har lidt af et problem.
Grunden til dette er, at output til stdout
bufferes af OS’et, og standardadfærden er (ofte) kun at skrive output til terminalen, når der kommer en newline. Tilføjelse af en fflush(stdout)
efter printf()
løser problemet:
printf("Enter a number: ");fflush(stdout);
Nu, ved at arbejde analogt, tror folk ofte, at fflush(stdin)
skal kassere ethvert ubrugt input, men hvis man tænker lidt over det, giver det ikke meget mening. Hvad betyder det at “skylle” en inputbuffer? Hvor bliver den “skyllet” hen? Hvis du flusher en outputbuffer, sendes output til den underliggende fil eller til terminalen, hvor det i sidste ende ville ende alligevel, men hvor ville input “i sidste ende alligevel” ende? Det kan man på ingen måde vide! Hvordan skal opførslen være, hvis input stream data kommer fra en fil eller en pipe eller en socket? Det er slet ikke klart for input streams, hvad adfærden af fflush()
skal være, men det er meget klart for output streams i alle tilfælde. Derfor er fflush()
kun defineret for output streams.
Grunden til, at den fejlagtige brug af fflush(stdin)
blev almindelig, er, at nogle få operativsystemer for mange år siden implementerede en ordning, hvor det virkede, som mange forventede, idet ubrugte input blev kasseret. Microsoft DOS er et godt eksempel. Overraskende nok implementerer moderne versioner af Linux også fflush()
for inputstreams.
Det rigtige at gøre med “ekstra” uønsket terminalinput er simpelthen at læse det og ikke gøre noget med det. Dette er næsten lige så nemt som at kalde fflush(stdin)
, virker overalt og er ikke afhængig af en formelt set udefineret adfærd.
C-standarden siger:
Hvis stream peger på en outputstream eller en opdateringsstream, hvor den seneste operation ikke var input, får fflush-funktionen alle ubeskrevne data for denne stream til at blive leveret til værtsmiljøet til at blive skrevet til filen; ellers er adfærden udefineret.
POSIX siger (henviser også eksplicit til C standard):
Hvis stream peger på en output stream eller en update stream, hvor den seneste operation ikke var input, skal fflush() få eventuelle uskrevne data for denne stream til at blive skrevet til filen, …
Men i Linux-manualsiden står der:
For output streams, fflush() tvinger en skrivning af alle bufferede data i brugerrummet for den givne output- eller opdateringsstream via streamens underliggende skrivefunktion. For inputstreams kasserer fflush() alle buffered data, der er hentet fra den underliggende fil, men som ikke er blevet forbrugt af programmet. Streamens åbne status er upåvirket.