使用 errno 和 ftell() 来区分错误和成功

Using errno with ftell() to distinguish error from success

我想弄明白ftell()是怎么用errno来区分成功和失败的。

我知道ftell()的return值会决定成败,但是可以return-1的值(ftell()失败) 即使成功,并且 return 被解释为带符号的值。

所以我检查 ftell() 的 return 值,如果它是负数,我查看 errno,如果 errno 不为零,我确定失败。

然而,问题是 errno 可以是非零的,即使是从以前的错误(对此表示怀疑)。在这种情况下,如何确定 ftell() 的成功或失败?

根据 的论点,在这种特殊情况下似乎不需要它,ftell 的 return 值应该足够了。

使用errno,通常是通过在您期望失败的函数之前将其值设置为0来完成的,并且被记录为设置errno的值。

稍后您验证它的值是否已设置,此值表示实现定义的错误代码。

§7.21.9.4 - ftell()

示例:

#include <errno.h>
//...

FILE* f = fopen("fil.txt", "r"); // skipping error check

errno = 0;

long res = ftell(f)); // on failure ftell returns -1

if(errno > 0 && res == -1)
{
    // error occured
    perror("ftell"); // you can use perror to print error message related to the error code
}

So I check the return value of ftell() and if that is negative

这是对文本文件的错误测试,因为“对于文本流,其文件位置指示符包含未指定的信息”。出错时,ftell() returns -1。对于文本文件,即使成功,ftell() 也可能 return 其他负数。

long position = ftell(stream);
// if (position < 0) Error(); // Weak
if (position == -1) Error();  // Better test

标准 C 库未定义 errno 设置为 ftell() 错误。由于 OP 的问题被标记为 linux,因此 OS 提供了在 ftell() 错误上设置 errno 的各种条件。那么当errnoftell()设置的时候,-1就是returned.

ftell() ... shall return -1, and set errno to indicate the error.

// Remains a good test on *nix.
if (position == -1) Error();  // Better test

然而 OP 担心“即使成功,也可能 return -1 的值(ftell() 失败),”

这是一个极端情况,文件非常长但仍然合法。由于return值为long,文件长度预计超过2G

// *nix systems
errno = 0;
if (position == -1 && errno) {
  Error();  // Better *nix test
}

如今许多支持此类大文件的系统也采用 64 位 long,无需进行此 && errno 测试(直到文件长度超过大约 9,000,000,000,000,000,000 字节 - 可能需要 20 年)。