Nie, to nie jest zachowanie POSIX, to zachowanie ISO (cóż, jest zachowanie POSIX ale tylko o ile są one zgodne z ISO).
Standardowe wyjście jest buforowane liniowo, jeśli można je wykryć w odniesieniu do urządzenia interaktywnego, w przeciwnym razie jest ono w pełni buforowane. Są więc sytuacje, w których printf
się nie spłukuje, nawet jeśli zostanie wysłany nowy wiersz, na przykład:
myprog >myfile.txt
Ma to sens ze względu na wydajność, ponieważ jeśli wchodzisz w interakcję z użytkownikiem, prawdopodobnie chce zobaczyć każdą linię. Jeśli wysyłasz dane wyjściowe do pliku, najprawdopodobniej na drugim końcu nie ma użytkownika (choć nie jest to niemożliwe, może on modyfikować plik). Teraz już mógł twierdzić, że użytkownik chce zobaczyć każdy znak, ale istnieją dwa problemy z tym.
Po pierwsze, nie jest bardzo wydajny. Po drugie, pierwotny mandat ANSI C miał przede wszystkim kodyfikować istniejące zachowanie, a nie wynajdować nowe , a decyzje projektowe zostały podjęte na długo przed rozpoczęciem procesu przez ANSI. Nawet ISO postępuje obecnie bardzo ostrożnie, zmieniając istniejące reguły w normach.
Co do tego, jak sobie z tym poradzić, jeśli fflush (stdout)
po każdym wywołaniu wyjściowym, które chcesz natychmiast zobaczyć, rozwiąże to problem.
Alternatywnie możesz użyć setvbuf
przed uruchomieniem stdout
, aby ustawić go na niebuforowany i nie będziesz musiał się martwić o dodanie wszystkich tych fflush
wierszy do swojego kodu:
setvbuf (stdout, NULL, _IONBF, BUFSIZ);
Pamiętaj, że jeśli tak, to może to wpłynąć na wydajność wysyłania danych do pliku. Należy również pamiętać, że wsparcie dla tego jest zdefiniowane w implementacji, nie jest gwarantowane przez standard.
Sekcja ISO C99 7.19.3/3
jest odpowiednim bitem:
Gdy strumień nie jest buforowany , postacie powinny pojawić się jak najszybciej ze źródła lub w miejscu docelowym. W przeciwnym razie znaki mogą być gromadzone i przesyłane do lub ze środowiska hosta jako blok.
Gdy strumień jest w pełni buforowany , znaki mają być przesyłane do lub ze środowiska hosta jako blok, gdy bufor jest zapełniony.
Gdy strumień jest buforowany w linii , znaki mają być przesyłane do lub ze środowiska hosta jako blok, gdy napotkany zostanie znak nowej linii.
Ponadto znaki mają być przesyłane jako blok do środowiska hosta, gdy bufor jest zapełniony, gdy żądanie jest przesyłane w niebuforowanym strumieniu lub gdy żądanie jest wprowadzane w strumieniu buforowanym w linii, który wymaga transmisji znaków ze środowiska hosta .
Obsługa tych cech jest zdefiniowana w ramach implementacji i może mieć na nie wpływ funkcje setbuf
i setvbuf
.