今天,我读了一个名为“fread of a fread?”的博客,我没有找到任何理由,所以我把它贴在这里等待任何天才。
首先,程序的目的是读取文件(readme.txt)并打印内容,然后使用Visual Studio 2010进行测试。
自述文件的内容是:
1234;
abcd;
ABCD;
自述文件的十六进制值为:
31 32 33 34 3b 0d 0a 61 62 63 64 3b 0d 0a 41 42 43 44 3b
以下是代码:
#include <stdio.h>
#include <string.h>
#define BUF_SIZE 1024
int main()
{
FILE *fp = NULL;
int rcnt = 0;
char rbuf[BUF_SIZE];
fp = fopen("readme.txt", "r");
if (NULL == fp)
{
printf("fopen error.\n");
return -1;
}
printf("--------------------------\n");
memset(rbuf, 0, BUF_SIZE);
fseek(fp, 0, SEEK_SET);
rcnt = fread(rbuf, 1, BUF_SIZE, fp);
printf("read cnt = %d\n", rcnt);
printf("%s\n", rbuf);
return 0;
}
这么简单的代码,预期的结果是:
--------------------------
read cnt = 17
1234;
abcd;
ABCD;
总共17个计数包括15个字符和2个\ n' 但我得到了以下结果:
--------------------------
read cnt = 17
1234;
abcd;
ABCD;D;
PS:如果用“rb”调用fopen函数,或者将宏BUF_SIZE定义得更小,我得到了正确的结果。
答案 0 :(得分:1)
fread()
不返回NUL终止的字符串,但是printf("%s")
要求NUL终止字符串。
您必须在读取缓冲区末尾添加'\ 0':rbuf[rcnt] = '\0'
。
并记住读取一个小于缓冲区大小的字节,为NUL字节留出空间。
答案 1 :(得分:0)
我认为将fread()
(一个二进制读取API)与文本文件一起使用是错误的。默认模式(如果您只是说"r"
)是文本。
请注意,FILE *
文本模式下的I / O通常会执行行终止转换,因此您可以假设这些行以\n
结尾,因为它们实际上可能以\r\n
结束(正如你的那样)。
这种转换可能会在某处造成混乱;这就是为什么切换到二进制模式使它再次起作用,因为在二进制模式下不会发生这种转换。