fread相同的文件,但返回不同的结果

时间:2012-12-20 14:21:54

标签: c windows fread

今天,我读了一个名为“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定义得更小,我得到了正确的结果。

2 个答案:

答案 0 :(得分:1)

fread()不返回NUL终止的字符串,但是printf("%s")要求NUL终止字符串。

您必须在读取缓冲区末尾添加'\ 0':rbuf[rcnt] = '\0'。 并记住读取一个小于缓冲区大小的字节,为NUL字节留出空间。

答案 1 :(得分:0)

我认为将fread()(一个二进制读取API)与文本文件一起使用是错误的。默认模式(如果您只是说"r")是文本。

请注意,FILE *文本模式下的I / O通常会执行行终止转换,因此您可以假设这些行以\n结尾,因为它们实际上可能以\r\n结束(正如你的那样)。

这种转换可能会在某处造成混乱;这就是为什么切换到二进制模式使它再次起作用,因为在二进制模式下不会发生这种转换。