更清晰的用途是什么?

时间:2019-06-25 13:42:01

标签: c

我试图了解何时应使用stdio函数assert

例如,如果我在有效的clearerr()fread()fwrite()并获得了一个短计数而FILE*为真,该怎么办?

根据我到目前为止所读的内容,ferrorfread()很健壮,并且会阻塞和/或重试(如果在较低级别的函数中可能发生锁和/或中断),因此使用fwrite()似乎毫无意义,因为clearerr()fread错误将是灾难性的,试图恢复毫无意义。

此外,fwrite仅告诉我有错误,而不是错误。

ferror()

4 个答案:

答案 0 :(得分:8)

clearerr至少有一个现实的用例:当您想模拟未以独占模式打开的文件上的tail -f时。这意味着另一个(或许多其他)进程在文件末尾写入数据,并且一个进程甚至在到达文件末尾后重复读取 以便查看是否有新数据到达。在这种情况下,可能看起来像这样:

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

答案 1 :(得分:3)

设置FILE的错误状态的功能(由ferror报告)即使以后成功调用也无法清除。同样,如果您在读取文件时遇到文件末尾,即使文件以后有更多可用数据,也不会自动清除它。

基本上,这意味着如果您正在使用ferror检查错误状态,并且有某种方法可以从中恢复,则ferror会一直指示错误直到您使用clearerr

在您的示例中,如果仅使用返回值fread作为终止读取的条件(即EOF和任何类型的错误都被认为是最终错误),则无需{{1} }:只需进入clearerr(也许可以使用fclose来确定是否打印错误消息)。

反之,如果ferror实际上是一个流,稍后可以在其上成功读取,并且您检测到(或假设)了特定的条件并重试,则应FILE在重试或您将在以后的尝试中继续看到旧的错误情况。

同样,如注释中所指出,clearerr也会清除文件末尾状态,因此在使用clearerr检查文件末尾时也是如此。 (不过请注意,阅读时通常shouldn't use !feof(file) as the loop condition。)

答案 2 :(得分:2)

clearerr()从流中清除错误和EOF标志。

FILE是这样的:

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

这会将file->errorfile->eof设置为0

执行此操作的某些原因包括文件I / O,例如文件提供EOF时,但随后会附加另一个程序(或另一个线程等)。如果在执行此操作后清除错误,则可以使程序充当tail -f的替代品。

答案 3 :(得分:1)

clearerr()清除错误和文件结束标志。

学步使用clearerr()

// Return -1 on end-of-file
// Return -2 on rare file error
// Else return the unsigned char value
int my_get_quandry() {
  // At this point, the file end-of-file flag may be set.
  // At this point, the file file error flag may be set.
  // They may both be set.

  // Attempt to read another
  int ch = fgetc();
  if (ch != EOF) {
    return ch;
  }
  // Now was the EOF due to a end-of file or error?
  // feof() is true if end-of-file just occurred OR if end-of-file was set earlier
  // ferror() is true if error just occurred OR if error was set earlier
  // If only one feof() or ferror() is true, we know  why EOF just occurred,
  // Yet if both set, we do not know.
  ...?
}

使用clearerr()

// Return -1 on end-of-file
// Return -2 on rare file error
// Else return the unsigned char value
int my_get_crystal() {
  clearerr(stdin);

  // Attempt to read another
  int ch = fgetc();
  if (ch != EOF) {
    return ch;
  }
  // Now EOF due to at most one reason
  if (feof(stdin)) return -1;
  if (ferror(stdin)) return -2;

  // if code reaches this point, it is due to the odd-ball platform of `char` having the
  // same range as `int`.  But let us leave that platform for another day.
  return ch;
}