我使用了fread函数,我得到的缓冲区大小为4,“读错误”。
为什么我的buffer
不是fileSize
?
这是我的代码:
FILE *fp;
char* buffer;
fp = fopen("help.txt","r");
if (fp == NULL){
fputs("Can't open Help file, Help.txt",stderr);
exit(1);
}
fseek(fp, 0, SEEK_END);
long fileSize = ftell(fp);
rewind(fp);
buffer = (char*) malloc (sizeof(char)*fileSize);
if(buffer == NULL){
fputs("Memory Allocation Error",stderr);
exit(2);
}
size_t result = fread(buffer,1,fileSize,fp);
if(result != fileSize){
fputs("Reading error\n",stderr);
printf("File Size : %lu\n",fileSize);
printf("Result : %lu\n",result);
printf("Buffer Size : %u\n",sizeof(buffer));
exit(3);
}
fputs(buffer,stdout);
fclose(fp);
free (buffer);
这是我运行程序时的输出:
Reading error
File Size : 224
Result : 219
Buffer Size : 4
答案 0 :(得分:5)
buffer
是char*
。指针大小为4个字节(对于32位系统)。所以sizeof(buffer)
将始终打印4。
分配具有特定大小的指针后,它指向的内存块的大小就是您分配的内存块。在这种情况下,sizeof(char)*fileSize
。
编辑哦,为了回答你的真正的问题,在Windows中没有问题,其中ftell以字节为单位报告大小,将每个CRLF计为2个字节。当您在缓冲区中读取此内容时,CRLF将转换为单字节\n
,从而减小结果文本的大小。
(现在不在Windows上,无法检查。)
答案 1 :(得分:3)
正确分配缓冲区。缓冲区大小使用sizeof(char)*fileSize
计算,而不是sizeof(buffer)
。您可以通过验证buffer
是否为空来测试缓冲区是否已分配。如果不是,那么它成功地分配了大小大于或等于您请求的大小的缓冲区。
问题是您以文本模式打开了文件。因此,Windows将用ANSI C要求的“\ n”替换文件中的所有“\ r \ n”序列。您可以接受此行为,也可以使用fp = fopen("help.txt","rb");
以二进制模式打开文件以读取所有未更改的内容。
答案 2 :(得分:2)
虽然您可以投射malloc
(对于C ++)的结果,但您不需要乘以sizeof(char)
always one。< / p>
sizeof
函数不会返回分配给运行时分配变量的字节数(您已在fileSize
中保留)。它只能按照您对静态分配变量的预期方式工作(例如int foo[BAR]; /* sizeof(foo) returns sizeof(int)*BAR bytes */
)。
#include <stdlib.h>
#include <stdio.h>
#define BAR 10
int main() {
int foo[BAR];
int *baz;
fprintf(stdout, "foo: %zu\n", sizeof(foo)); /* 40 */
baz = malloc(sizeof(int) * BAR);
if (baz != NULL) {
fprintf(stdout, "baz: %zu\n", sizeof(baz)); /* not 40, but sizeof(int*) */
free(baz);
}
else {
fprintf(stdout, "could not allocate memory for baz\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
$ gcc -Wall -o test test.c
$ ./test
foo: 40
baz: 8
在64位系统上,指针是8个字节。