在32位系统上,如果以二进制模式打开的文件的当前位置指示器超过2GB点,那么ftell返回什么?在 C99 标准中,由于ftell必须返回long int(最大值是2**31-1),所以这种未定义的行为是吗?

最佳答案

在长整数上
long int应该至少为32位,但是C99标准并未将其限制为32位。
C99标准确实提供了便利类型,例如int16_tint32_t等,它们映射到目标平台的正确位大小。

在ftell/fseek上

在绝大多数32位体系结构系统上,ftell()fseek()限制为32位(包括符号位)。因此,当有大文件支持时,您会遇到此2GB问题。
fseekftell的POSIX.1-2001和SysV函数是fseekoftello,因为它们使用off_t作为偏移量的参数。

您确实需要使用-D_FILE_OFFSET_BITS=64定义编译,或者在包含stdio.h之前在某处定义它,以确保off_t是64位。

cert.org secure coding guide上阅读有关此内容的信息。

关于ftell和long int的大小的困惑

C99说long int必须至少为32位,但没有说它不能更大

在x86_64体系结构上尝试以下操作:

#include <stdio.h>

int main(int argc, char *argv[]) {
    FILE *fp;
    fp = fopen( "test.out", "w");
    if ( !fp )
        return -1;
    fseek(fp, (1L << 34), SEEK_SET);
    fprintf(fp, "\nhello world\n");
    fclose(fp);
    return 0;
}

请注意,1L只是long,这将产生一个17GB的文件,并将"\nhello world\n"粘贴到该文件的末尾。您可以通过简单地使用tail -n1 test.out或显式使用以下命令来验证其中的内容:



请注意,dd通常使用(1 << 9)的块大小,因此34 - 9 = 25将转储'\nhello world\n'

关于c - ftell超过2GB的位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16696297/

10-10 14:01