gpt4 book ai didi

c++ - fscanf : is error or EOF possible without EOF returned?

转载 作者:行者123 更新时间:2023-11-30 02:15:05 26 4
gpt4 key购买 nike

我有一个 C++ 程序,它从一个文件中读取我希望有一堆格式相同的记录。如果遇到意外情况,无论是记录格式不正确还是输入失败,我都想停止阅读,我想区分这些不同的情况。

我看过 this answer并查看了 fscanf() documentation我不确定 fscanf() 是否可以在不返回 EOF 的情况下指示错误或 EOF。根据我对这两个链接的理解,即使 fscanf() 返回 0 或更大的值,也可能发生错误或 EOF,因此我必须调用 ferror()feof() 而不管 fscanf() 返回什么值。我似乎无法找到 EOF 的返回值对调用者有何用处。

假设我希望我的文件包含一堆具有 4 个值的记录。下面的代码能否正确处理任何文件结尾和输入错误情况?

  int ret;
int field1;
int field2;
int field3;
int field4;
while ((ret = fscanf(pFile, "%d %d %d %d", &field1, &field2, &field3,
&field4)) == 4) {
// do whatever with fields
}
if (ferror(fp)) {
// some input error occurred
} else if (feof(fp)) {
// end of file occurred
} else {
assert(ret != EOF);
// encountered record that didn't match expected format
}

更新:所以我要添加来自 cppreference 的文档因为它在描述什么条件不再导致返回 EOF 方面似乎略有不同。

最佳答案

Is error or EOF possible without EOF returned?

是的。您还可以获得 0 到 3 之间的返回值。cplusplus.com 有点草率。我们来看看cppreference.com's page相反。

Return value: Number of receiving arguments successfully assigned (which may be zero in case a matching failure occurred before the first receiving argument was assigned), or EOF if input failure occurs before the first receiving argument was assigned.

有几种不同的情况。让我们将其分解为案例:

  1. 如果它已成功分配给第一个接收参数,那么您将得到一个正值,这是有保证的。假设它被分配给两个变量然后命中 EOF。它将返回 2 并且 feof() 将返回 true。

  2. 否则,如果它没有分配给第一个接收参数并且匹配失败,它将返回0。什么是匹配失败?那是当它匹配一个像 %d 这样的说明符并且没有得到一个有效的整数时。如果输入是 foobar 那么 %d 将无法匹配。

    或者,不太常见的情况是,它正在寻找文字字符但没有看到它。例如,如果您的格式字符串希望每个数字都括在方括号中 ("[%d] [%d] [%d] [%d]"),那么它将返回 0 如果输入不是以 [.

  3. 开头
  4. 否则,如果它没有分配给第一个接收参数并收到 EOF 或读取错误,它将返回 EOF。请注意,读取 错误不同于匹配 错误。读取错误是指操作系统返回尝试从磁盘读取的 I/O 错误。

    EOF 的返回值表示文件结束或 I/O 错误。如果您不关心区别,您可以放弃循环并继续执行该程序。但是,如果您想在 ferror() 上打印一条错误消息并将 feof() 视为成功,那么检查 ret 是不够的;您必须调用其中一个或两个函数。是否要这样做取决于您。

Say I expect my file to have a bunch of records with 4 values. Would the code below properly handle any end of file and input error conditions?

是的。我觉得不错。


就其值(value)而言,我建议不要使用 scanf()fscanf()。它们很复杂,使处理输入错误变得比必要的更困难。这个问题就是一个很好的示范。最好使用 fgets() 来读取整行并使用 sscanf() 来解析它。那样的话,如果有错误的输入,您就不会有部分行干扰 future 的读取。

关于c++ - fscanf : is error or EOF possible without EOF returned?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56613955/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com