La questione dei test per una condizione di errore è venuto a causa di un corner case in C.
fgetc()
restituisce un int
. I valori sono compresi nell'intervallo unsigned char
e EOF
, (un numero negativo).
int ch;
while ((ch = fgetc(fp)) != EOF) {
// do something with ch
}
if (ferror(fp)) Handle_InputError();
if (feof(fp)) Handle_EndOffFile(); // Usually nothing special
Eppure C permette unsigned char
di avere una gamma più ampia rispetto al numero positivo di int
. La conversione da unsigned char
a int
ha un comportamento definito dall'implementazione che può comportare la conversione di un valore unsigned char
in un valore negativo int
e uno che corrisponde a EOF
.
Tali piattaforme sono rare e non nel flusso principale del 2015. La maggior parte avrà UCHAR_MAX <= INT_MAX
e lo stile sopra è in genere utilizzato. Dubbi che queste piattaforme diventeranno sempre comuni a causa della quantità di codice, come sopra, che si basa su EOF
distinto da unsigned char
convertito in int
.
codice dovrebbe avere bisogno per gestire il caso raro in cui UCHAR_MAX > INT_MAX
, quindi
int c;
for (;;)
{
c = fgetc(file);
if (c == EOF) {
if (feof(file)) break;
if (ferror(file)) break;
// fall through if both if's fail.
}
// do stuff with c
}
Il riferimento popolare in while (!feof (file)) always wrong? evidenzia il codice di errore fa spesso utilizzando i risultati di fgetc(in)
prima di controllare per i problemi. Entrambi i codici sopra controllano le condizioni di errore prima di utilizzare il risultato di fgetc()
.
Il secondo codice gestisce tutte le situazioni, tra cui quelli che si possono applicare solo a un computer seduto in un qualche mucchio di spazzatura lungo dimenticato. Il primo è molto più comune.
Utilizzare la prima versione. Il secondo non è "più robusto" ma richiede molto più codice. Inoltre non riesce a verificare la presenza di una condizione di errore. – fuz
@user - No, il modo C++ corretto è 'while (cin >> c)', e assolutamente ** not ** 'mentre (! Cin.eof())'. Vedi [Perché isostream :: eof all'interno di una condizione di ciclo considerata errata] (http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) –
@Kninnug It non è un duplicato di quella domanda. – ashiquzzaman33