2013-05-01 22 views
6

Da The GNU C Programming Tutorial:Perché la funzione fgets è deprecata?

La funzione fgets ("file get stringa") è simile alla funzione di ottiene. Questa funzione è deprecata - ciò significa che è obsoleto ed è fortemente consigliato non utilizzarlo - perché è pericoloso. È pericoloso perché se i dati di input contengono un carattere nullo , non puoi dirlo. Non utilizzare fgets a meno che non si sappia che i dati non possono contenere un valore nullo. Non usarlo per leggere i file modificati dall'utente perché, se l'utente inserisce un carattere nullo, è necessario o gestirlo correttamente o stampare un messaggio di errore chiaro. Utilizzare sempre getline o getdelim invece di fgets se possibile.

ho pensato la funzione fgets arresta quando incontra un \0 o \n; perché questa pagina di manuale suggerisce che un byte null è "pericoloso" quando fgets dovrebbe gestire correttamente l'input? Inoltre, qual è la differenza tra getline e fgets ed è la funzione fgets veramente considerata deprecata nel C99 o futuri standard C?

risposta

12

No, fgets non è in realtà deprecato in C99 o lo standard corrente, C11. Ma l'autore di quel tutorial ha ragione che fgets non si fermerà quando incontra un NUL e non ha alcun meccanismo per riportare la sua lettura di un tale personaggio.

La funzione fgets legge al massimo uno meno del numero di caratteri specificato per n dal flusso puntato da stream nell'array puntato da s. Nessun carattere aggiuntivo viene letto dopo un carattere di nuova riga (che viene mantenuto) o dopo la fine del file.

(§7.21.7.2)

di GNU getdelim e getline sono stati standardizzati in POSIX 2008, quindi se siete destinati a una piattaforma di POSIX, quindi potrebbe non essere una cattiva idea quella di utilizzare quelli invece.

EDIT ho pensato che non c'era assolutamente alcun modo sicuro da usare fgets a fronte di caratteri NUL, ma R .. (vedi commenti) ha sottolineato c'è:

char buf[256]; 

memset(buf, '\n', sizeof(buf)); // fgets will never write a newline 
fgets(buf, sizeof(buf), fp); 

Ora guardate per l'ultima non- \n carattere in buf. In realtà non consiglierei questo kludge.

+0

Quindi 'fgets' continua a leggere i byte null passati, cercando solo il carattere di nuova riga? –

+1

@VilhelmGray: è giusto, e non ti dirà che è successo. Non c'è modo di essere sicuri che il primo '\ 0' che trovi sia stato aggiunto da 'fgets' o no. I byte null –

+4

non appartengono ai file ** di testo **.'fgets()' è stato progettato per funzionare con file di testo: l'uso di 'fgets()' con file di dati binari non è raccomandato. – pmg

5

Questa è solo propaganda GNU. In nessun caso ufficiale è fgets deprecato. gets tuttavia è pericoloso e deprecato.

+3

'gets' è stato effettivamente * rimosso * dallo standard ISO C 2011. (Non è stato ufficialmente dichiarato obsoleto o obsoleto in C99). –

+3

@KeithThompson: Sezione 7.26.9 di ISO/IEC 9899: 1999 TC3 dice "La funzione' get' è obsoleta ed è deprecata. " quindi credo che 'gets' fosse ufficialmente deprecato in C99. –

+0

Questa lingua è stata aggiunta in uno dei TC o nella pubblicazione originale di C99? –