Răspunsul la această întrebare este că fflush(stream)
este definit în mod formal doar pentru fluxurile de ieșire, deci fflush(stdout)
este OK, dar fflush(stdin)
nu este.
Scopul lui fflush(stream)
este de a face ca sistemul de operare să curețe orice tampon către fișierul de bază. Pentru un exemplu de utilizare legitimă, studenții au adesea probleme de genul „promptul meu nu apare!” dacă fac ceva de genul:
printf("Enter a number: ");
Cu toate acestea, ei descoperă că acest lucru funcționează foarte bine:
printf("Enter a number:\n");
Desigur, ei nu doresc o linie nouă după promptul lor, așa că au o mică problemă.
Motivul este că ieșirea către stdout
este pusă în buffer de către sistemul de operare și comportamentul implicit este (adesea) de a scrie efectiv ieșirea pe terminal doar atunci când se întâlnește o linie nouă. Adăugarea unui fflush(stdout)
după printf()
rezolvă problema:
printf("Enter a number: ");fflush(stdout);
Acum, lucrând prin analogie, oamenii cred adesea că fflush(stdin)
ar trebui să arunce orice intrare nefolosită, dar dacă vă gândiți puțin, acest lucru nu prea are sens. Ce înseamnă să „arunci” un buffer de intrare? Încotro este „curățat”? Dacă se golește un buffer de ieșire, ieșirea este trimisă la fișierul de bază sau la terminal, unde ar fi ajuns oricum, dar unde ar ajunge „oricum” intrarea? Nu avem de unde să știm! Care ar trebui să fie comportamentul în cazul în care datele din fluxul de intrare provin dintr-un fișier, o conductă sau un socket? Nu este deloc clar pentru fluxurile de intrare care ar trebui să fie comportamentul lui fflush()
, dar este foarte clar pentru fluxurile de ieșire în toate cazurile. Prin urmare, fflush()
este definit numai pentru fluxurile de ieșire.
Motivul pentru care utilizarea eronată a fflush(stdin)
a devenit obișnuită este că, cu mulți ani în urmă, câteva sisteme de operare au implementat o schemă în care funcționa așa cum se așteptau mulți oameni, eliminând intrările nefolosite. Microsoft DOS este un bun exemplu. În mod surprinzător, versiunile moderne de Linux implementează, de asemenea, fflush()
pentru fluxurile de intrare.
Ceea ce trebuie făcut cu intrarea nedorită „în plus” a terminalului este pur și simplu să o citești și să nu faci nimic cu ea. Acest lucru este aproape la fel de ușor ca și apelarea lui fflush(stdin)
, funcționează peste tot și nu se bazează pe un comportament formal nedefinit.
Standardul C spune:
Dacă stream indică un flux de ieșire sau un flux de actualizare în care cea mai recentă operațiune nu a fost de intrare, funcția fflush face ca orice date nescrise pentru acel flux care urmează să fie livrate în mediul gazdă să fie scrise în fișier; în caz contrar, comportamentul este nedefinit.
POSIX spune (de asemenea, se raportează în mod explicit la standardul C):
Dacă stream indică un flux de ieșire sau un flux de actualizare în care cea mai recentă operațiune nu a fost de intrare, fflush() determină ca orice date nescrise pentru acel flux să fie scrise în fișier, ….
Dar pagina de manual Linux spune:
Pentru fluxurile de ieșire, fflush() forțează o scriere a tuturor datelor tamponate în spațiul utilizatorului pentru fluxul de ieșire sau de actualizare dat prin intermediul funcției de scriere subiacente a fluxului. Pentru fluxurile de intrare, fflush() elimină toate datele stocate în memoria tampon care au fost preluate din fișierul de bază, dar care nu au fost consumate de aplicație. Starea deschisă a fluxului nu este afectată.
.