在32位系统上,如果以二进制模式打开的文件的当前位置指示器超过2GB点,那么ftell
返回什么?在 C99 标准中,由于ftell
必须返回long int
(最大值是2**31-1
),所以这种未定义的行为是吗?
最佳答案
在长整数上long int
应该至少为32位,但是C99标准并未将其限制为32位。
C99标准确实提供了便利类型,例如int16_t
和int32_t
等,它们映射到目标平台的正确位大小。
在ftell/fseek上
在绝大多数32位体系结构系统上,ftell()
和fseek()
限制为32位(包括符号位)。因此,当有大文件支持时,您会遇到此2GB问题。fseek
和ftell
的POSIX.1-2001和SysV函数是fseeko
和ftello
,因为它们使用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/