No, non è un comportamento POSIX, è un comportamento ISO (beh, è un comportamento POSIX ma solo nella misura in cui sono conformi a ISO).
L'output standard è bufferizzato se può essere rilevato come riferimento a un dispositivo interattivo, altrimenti è completamente bufferizzato. Quindi ci sono situazioni in cui printf
non si scarica, anche se viene inviata una nuova riga, come ad esempio:
myprog >myfile.txt
Questo ha senso per l'efficienza poiché, se stai interagendo con un utente, probabilmente vogliono vedere ogni riga. Se stai inviando l'output a un file, è molto probabile che non ci sia un utente all'altro capo (anche se non impossibile, potrebbero essere in coda al file). Ora si potrebbe sostenere che l'utente vuole vedere ogni personaggio, ma ci sono due problemi con questo.
Il primo è che non è molto efficiente. Il secondo è che il mandato originale ANSI C era di codificare principalmente il comportamento esistente , piuttosto che inventare un nuovo comportamento e che le decisioni di progettazione venivano prese molto prima che ANSI iniziasse il processo. Anche ISO oggi calpesta molto attentamente quando si modificano le norme esistenti negli standard.
Quanto a come gestirlo, se fflush (stdout)
dopo ogni chiamata in uscita che si desidera vedere immediatamente, ciò risolverà il problema.
In alternativa, puoi utilizzare setvbuf
prima di operare stdout
, per impostarlo su senza buffer e non dovrai preoccuparti di aggiungere tutte quelle fflush
righe al tuo codice:
setvbuf (stdout, NULL, _IONBF, BUFSIZ);
Basta tenere a mente che può influire sulle prestazioni un po 'se si sta inviando l'output in un file. Inoltre, tieni presente che il supporto per questo è definito dall'implementazione, non garantito dallo standard.
La sezione ISO C99 7.19.3/3
è il bit rilevante:
Quando uno stream è senza buffer , i personaggi devono apparire dalla sorgente o dalla destinazione il più presto possibile. Altrimenti i caratteri possono essere accumulati e trasmessi da o verso l'ambiente host come un blocco.
Quando uno stream è completamente bufferizzato , i caratteri devono essere trasmessi da o verso l'ambiente host come un blocco quando viene riempito un buffer.
Quando uno stream ha un buffer di linea , i caratteri devono essere trasmessi da o verso l'ambiente host come un blocco quando viene rilevato un carattere di nuova riga.
Inoltre, i caratteri devono essere trasmessi come blocco all'ambiente host quando viene riempito un buffer, quando viene richiesto l'input su un flusso senza buffer o quando viene richiesto l'input su un flusso con buffer di linea che richiede la trasmissione di caratteri dall'ambiente host .
Il supporto per queste caratteristiche è definito dall'implementazione e può essere influenzato dalle funzioni setbuf
e setvbuf
.