2013-05-21 31 views
6

Odkąd odkryto fflush(stdin) nie jest przenośnym sposobem radzenia sobie ze znanym problemem „nowalinia czai się w buforze wejściowym”, I zostały z wykorzystaniem następujących po muszę użytku scanf:Czy fseek (stdin, 1, SEEK_SET) lub przewijanie do tyłu (stdin) mogą być użyte do opróżnienia bufora wejściowego zamiast nieprzenośnego fflush (stdin)?

while((c = getchar()) != '\n' && c != EOF); 

Ale dzisiaj natknąłem się tej linii, która zauważyła, że ​​od cplusplus.com on fflush:

fflush (...) w plikach otwartych dla aktualizacji (tj otwarte zarówno czytanie i pisanie), strumień powinien być przepłukany afte r operacja wyjściowa przed wykonaniem operacji wprowadzania. Można to zrobić albo poprzez repozycjonowanie (fseek, fsetpos, przewijanie do tyłu) lub dzwoniąc bezpośrednio fflush

W rzeczywistości, czytałem, że przed wielu times.So Chcę potwierdzić, czy mogę po prostu użyć dowolnego z następujących przed scanf() służyć temu samemu celowi służy fflush(stdin) że gdy jest obsługiwany:

fseek(stdin,1,SEEK_SET); 
rewind(stdin); 

PSrewind(stdin) wydaje się całkiem bezpieczne i wykonalne, by opróżnić bufor, nie mam racji?

Mistake powinienem wymienić fseek(stdin,0,SEEK_SET) jeśli mówimy o stdin jak nie możemy użyć dowolnego przesunięcia inna niż 0 lub jeden zwrócony przez ftell() w tej sprawie.

+0

Od swojej cytat:”... * strumień powinien być przepłukany po operacji wyjścia * .. . ". Czy spodziewasz się wykonywać operacje wyjściowe na 'stdin', aby wymagać' fflush (stdin) '? To wydaje się głupie! Chcesz * zapisać * do strumienia * tylko do odczytu * ?! Dlaczego nie opisujesz, co masz na myśli, mówiąc: * opróżnij bufor * lub czego chcesz "fflush (stdin)"? Możesz również rozważyć, co 'fflush' faktycznie robi zgodnie z [podręcznikiem nie w C++] (http://pubs.opengroup.org/onlinepubs/009695399/functions/fflush.html). W końcu to jest C, nie C++ ... – Sebivor

+0

@undefinedbehaviour To nie jest mój cytat. To pochodzi z http://www.cplusplus.com/reference/cstdio/fflush/ i mówi o obu strumieniach I/O, nie 'stdin' w szczególności. Chodzi mi o to, że podczas odczytu z' stdin', zgodnie z tym paragrafem, moglibyśmy go wypróżnić za pomocą 'rewind()' lub 'fseek()' na tym. – Jugni

+0

'stdin' jest otwarte tylko do odczytu, a nie do aktualizacji (zarówno do odczytu, jak i zapisu). Nie mylić tych dwóch trybów. Często zdarza się, że ta witryna jest bardzo niedokładna. Znajdź inną ręczną witrynę. Polecam grupę otwartą. – Sebivor

Odpowiedz

3

Jest to jedyny przenośny idiom użycia:

while((c = getchar()) != '\n' && c != EOF); 

kilka wątków w tym this wyjaśnić dlaczego feesk zwykle nie działa. za dużo tych samych powodów wątpię rewind będzie działać albo w rzeczywistości strona mężczyzna mówi, że jest równoważne:

(void) fseek(stream, 0L, SEEK_SET) 
+0

Przeczytałem ten link, który podałeś. Ale wydaje się to trochę trudne do zrozumienia. Czy umieścisz część tego linku, która jest istotna dla tego pytania w kilku prostych liniach? – Jugni

+0

@Jugni Ten komentarz naprawdę wyjaśnia to dobrze http://stackoverflow.com/questions/4917801/using-fseek-with-a-file-pointer-that-points-to-stdin#comment5479013_4917849 zasadniczo strumień nie jest przechowywany w dowolnym miejscu. Jeśli chcesz przeszukać dane, wczytaj je do pamięci. –

+0

Ale czytam, że strumień jest domyślnie buforowany. Jestem pewien, że 'stdin' i' stdout' są buforowane. Wszystkie strumienie są otwierane za pomocą 'fopen()' – Jugni