2013-05-21 32 views
6

Da quando ho scoperto fflush(stdin) non è un modo portabile per affrontare il problema familiare di "ritorno a capo in agguato nel buffer di input", ho utilizzato il seguente quando ho devo uso scanf:È possibile utilizzare fseek (stdin, 1, SEEK_SET) o rewind (stdin) per svuotare il buffer di input anziché fflush non portatile (stdin)?

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

Ma oggi mi sono imbattuto in questa linea che avevo notato da cplusplus.com on fflush:

fflush() ... in file aperti per l'aggiornamento (ad esempio, aperto sia la lettura e la scrittura), il flusso deve essere lavata afte r un'operazione di uscita prima di eseguire un'operazione di input. Questo può essere fatto sia con riposizionamento (fseek, fsetpos, riavvolgimento) o chiamando esplicitamente fflush

In realtà, ho letto che prima di molti times.So voglio confermare se posso usare semplicemente qualcuno dei seguenti prima che il scanf() per servire allo stesso scopo che fflush(stdin) serve quando è supportato:

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

PSrewind(stdin) sembra abbastanza sicura e praticabile per svuotare il buffer, mi sbaglio?

Mistake Avrei detto fseek(stdin,0,SEEK_SET) se stiamo parlando di stdin come non si può usare qualsiasi scostamento diverso da 0 o quello restituito dalla ftell() in quel caso.

+0

Dal tuo preventivo," ... * il flusso deve essere lavata dopo un'operazione di uscita * .. . ". Ti aspetti di eseguire operazioni di output su 'stdin', per richiedere' fflush (stdin) '? Sembra sciocco! Vuoi * scrivere * su un flusso * di sola lettura * ?! Perché non descrivi cosa intendi con * svuotare il buffer *, o cosa vuoi fare con 'fflush (stdin)'? Si potrebbe anche voler considerare cosa 'fflush' effettivamente fa secondo [un manuale non C++] (http://pubs.opengroup.org/onlinepubs/009695399/functions/fflush.html). Dopo tutto, questo è C, non C++ ... – Sebivor

+0

@undefinedbehaviour Quella non è la mia citazione.Quello è preso da http://www.cplusplus.com/reference/cstdio/fflush/ e che parla di entrambi i flussi I/O, non 'stdin' in particolare. Quello che volevo dire è che, leggendo da' stdin', secondo quel paragrafo, saremmo in grado di svuotarlo usando 'rewind()' o 'fseek()' su di esso. – Jugni

+0

'stdin' è aperto solo per lettura, non per aggiornamento (sia in lettura che in scrittura). Non confondere queste due modalità. Non è raro che quel sito sia grossolanamente inaccurato. Trova un altro sito manuale. Raccomando opengroup. – Sebivor

risposta

3

Questo è l'unico linguaggio portatile da utilizzare:

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

Fili tra cui this uno spiegare perché feesk di solito non funziona. per le stesse ragioni dubito rewind avrebbe funzionato sia, in realtà la pagina man dice che è equivalente a:

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

Ho letto il link che hai dato.Ma sembra un po 'difficile da capire.Puoi mettere la porzione di quel collegamento che è rilevante per questa domanda in poche semplici righe? – Jugni

+0

@Jugni Questo commento lo spiega molto bene http://stackoverflow.com/questions/4917801/using-fseek-with-a-file-pointer-that-points-to-stdin#comment5479013_4917849 fondamentalmente uno stream non è memorizzato da nessuna parte. Se vuoi cercare intorno ai dati, leggilo nella memoria. –

+0

Ma ho letto che uno stream è tamponato di default. Sono abbastanza sicuro che 'stdin' e' stdout' sono bufferizzati. Come tutti gli stream aperti con 'fopen()' – Jugni