A cosa serve clearerr?

A cosa serve clearerr?

Esiste almeno un caso d'uso nel mondo reale per clearerr :quando vuoi imitare tail -f su un file che non è aperto in modalità esclusiva. Ciò significa che un altro (o molti altri) processi scrivono alla fine di un file e un processo legge ripetutamente anche dopo aver raggiunto la fine del file per vedere se sono arrivati ​​nuovi dati. In tal caso, potrebbe essere simile a:

for (;;) {
    if (NULL == fgets(line, sizeof(line), fd)) {
        sleep(n);
        clearerr(fd);     // reset EOF condition
    }
    else {
        fputs(line, fdout);
    }
}

Funzioni che impostano lo stato di errore di un FILE (come riportato da ferror ) non cancellarlo anche se successivamente chiamato con successo. Allo stesso modo, se incontri la fine del file durante la lettura, non verrà cancellata automaticamente anche se il file in seguito ha più dati disponibili.

Fondamentalmente questo significa che se stai usando ferror per verificare la presenza di uno stato di errore e hai un modo per risolverlo, il ferror continuerà a indicare un errore finché non utilizzerai clearerr .

Nel tuo esempio, se usi solo il valore di ritorno di fread in quanto condizione per terminare la lettura (cioè, EOF e qualsiasi tipo di errore sono considerati definitivi), non è necessario clearerr :passa a fclose (e magari usare ferror per determinare se stampare un messaggio di errore).

D'altra parte, se il FILE è in effetti uno stream su cui la lettura può in seguito avere esito positivo e tu rilevi (o presupponi) quella condizione specifica e riprova, dovresti clearerr prima di riprovare o continuerai a visualizzare la vecchia condizione di errore nei tentativi futuri.

Allo stesso modo, come sottolineato nei commenti, clearerr cancella anche la fine dello stato del file, quindi questo vale anche quando si utilizza feof per controllare la fine del file. (Nota, tuttavia, che generalmente non dovresti usare !feof(file) come condizione del ciclo durante la lettura.)


clearerr() cancella l'errore e i flag EOF da uno stream.

Pronuncia FILE erano così:

typedef struct {
    int fd;
    char *buf;
    int error;
    int eof;
} FILE;
FILE *file;

Questo imposterebbe file->error e file->eof a 0 .

Alcuni motivi per farlo includono l'I/O di file, ad esempio quando un file fornisce EOF, ma poi un altro programma (o un altro thread, ecc.) si aggiunge ad esso. Se cancelli l'errore dopo averlo fatto, puoi fare in modo che il tuo programma agisca come una sorta di tail -f -sostituire.