在 C 中确定缓冲区分配的文件大小

determine size of file for buffer allocation in c

提问人:real_G 提问时间:11/14/2020 最后编辑:chqrliereal_G 更新时间:11/14/2020 访问量:544

问:

我写的这段代码应该遍历 一个文件,并在每次它去字符时递增大小计数器:+1

while (fgetc(input) != EOF)
    size++; 

if (feof(input)) {
    buff = (char *)malloc(sizeof(char) * size + 1); 
}

当未到达文件末尾时,大小正在递增。If 和 buffer-size 可以确定。EOF-> feof==true

只是想知道是否有可能这样做,或者是否有更好的方法可以做到这一点。

C 文件 malloc eof feof

评论

1赞 wildplasser 11/14/2020
只需省略条件即可。它不是必需的。(除非你想区分错误和EOF,这很少需要)if(feof(input))

答:

0赞 chqrlie 11/14/2020 #1

假设初始化到循环之前并且位于流的开头,则循环将正确确定可以从文件中读取的字节数。size0input

循环后测试可区分文件结束和读取错误情况。通常没有必要进行此区分,因此您可以删除此测试。feof()

malloc(sizeof(char) * size + 1)分配正确的字节数以将文件读取为 C 字符串,但表达式不正确:根据定义,它应该是 either 或原样。sizeof(char) * (size + 1)size + 1sizeof(char)1

请注意,您需要显式设置 null 终止符,因为不会初始化它分配的块。malloc()

另请注意,某些流(例如终端)可能无法查找,因此,如果您需要倒带流以读取字节,此方法可能会失败。

最后请注意,它可能小于使用 2 个字节作为行尾标记(如 MS/DOS 和 Windows)的旧系统上的文件长度。size

评论

0赞 real_G 11/15/2020
谢谢!我是 C-> 编程的新手,使用 calloc 而不是 malloc 可以解决必须显式设置的 null 终止符的问题吗?关于可能无法查找的终端 - >我认为函数 rewind() 也可以解决这个问题 - 因为它将指针重置为缓冲区开头。
0赞 chqrlie 11/15/2020
calloc()Indeed 将块初始化为所有位零,因此无需设置 null 终止符。关于 和 之间没有区别,虽然 返回一个成功指标,而 是一个 void 函数,但这并不意味着它总是成功。如果从流中读取的字符数多于流缓冲区中可容纳的字符数,则必须可查找该流才能将流重置为文件的开头。除了终端,管道也不是可寻取的把手。rewind()fseek(input, 0L, SEEK_SET)rewind()fseek()rewind()rewind()
1赞 gobinda 11/14/2020 #2

使用 ftell() 函数大小可以确定,因为

fseek( input, 0, SEEK_END );
size = ftell( input);

然后将指针设置为文件开头,

fseek( input, 0, SEEK_SET );

评论

0赞 chqrlie 11/15/2020
C17 7.21.9.4 ftell 函数:ftell 函数获取 stream 指向的流的文件位置指示符的当前值。对于二进制流,该值是从文件开头开始的字符数。对于文本流,其文件位置指示器包含未指定的信息,可由 fseek 函数使用,用于将流的文件位置指示器返回到 ftell 调用时的位置;两个此类返回值之间的差异不一定是写入或读取的字符数的有意义的度量。