fread在缓冲区中存储随机字符

时间:2013-07-17 18:51:27

标签: c++ readfile fread

我只是尝试使用fread读取文件并输出内容。它部分工作。它正确地输出所有内容但它以一堆随机字符结束。

#include <iostream>

using namespace std;

void ReadFile(char* filename,char*& buffer)
{
    FILE *file = fopen(filename,"rb");

    fseek(file,0,SEEK_END);
    int size = ftell(file);
    rewind(file);

    buffer = new char[size];
    memset(buffer,0,size);

    int r = fread(buffer,1,size,file);
    cout << buffer;

    fclose(file);
}

int main()
{
    char* buffer;
    ReadFile("test.txt",buffer);
    cin.get();
}

在这种情况下,假设'size'为50。由于某种原因,在调用fread之后,缓冲区的大小最终会达到55或56。我在使用它之前清空了缓冲区并尝试输出它,一切正常(它是空的)。在调用fread之后,缓冲区以某种方式变得更大并且充满了随机字符。我已经在十六进制编辑器中打开了文本文件,以确保没有任何我没有看到但没有。该文件是50个字节。 fread返回读取的字节数,在这种情况下返回'r','r'应该是它应该是什么。所以这些字节来自哪个母亲?

简化:fread返回正确读取的字节数,但缓冲区在调用fread后以某种方式使自身变大,然后用随机字符填充它。为什么呢?

我不能为我的生活弄清楚这是怎么回事。

此外,在任何人给我一个简单的修复之前,我已经知道我可以做缓冲[r] ='\ 0'并且不再输出任何随机字符,但我更愿意知道为什么会发生这种情况。< / p>

3 个答案:

答案 0 :(得分:4)

<cout << char* buffer运算符需要C字符串,因此您需要空终止int size = ftell(file)+1; // Leave space for null terminator ... int r = fread(buffer,1,size-1,file); buffer[r] = '\0'; cout << buffer;

buffer

您看到的额外字符是operator <<结束后内存地址中的随机数据。 '\0'不知道字符串已结束,因此它会继续打印,直到找到第一个{{1}}字节。

答案 1 :(得分:0)

您可能只是忘记了null终止缓冲区。相反,使用cout.write并提供缓冲区的长度:

添加一些错误处理(不够,但是开始),缺少包含和使用语句:http://coliru.stacked-crooked.com/view?id=8bc4f3b7111554c705de96450d806104-f674c1a6d04c632b71a62362c0ccfc51

#include <iostream>
#include <string>
#include <vector>
#include <cstring>

using namespace std;

void ReadFile(const char* filename,char*& buffer)
{
    FILE *file = fopen(filename,"rb");

    if (!file)
         return;

    fseek(file,0,SEEK_END);
    int size = ftell(file);
    rewind(file);

    buffer = new char[size];
    memset(buffer,0,size);

    int r = fread(buffer,1,size,file);
    cout.write(buffer, r);

    fclose(file);
}

int main()
{
    char* buffer;
    ReadFile("test.txt",buffer);
    cin.get();
}

答案 2 :(得分:0)

实际上cout会打印字符串,直到它没有得到任何NULL字符。这意味着终止需要NULL。

但是,分配NULL并不是一个好的解决方案。那时你的数据可能是二进制文件,cout只打印输出到NULL char。我的意思是二进制数据可以是任何东西,它也可能是一个不可读的字符。并且cout会将其视为NULL char。这就是为什么使用for循环直到字符串或数据集的长度总是安全的。

len = strlen(buffer)
for (int i = 0; i < len; i++)
     printf("%c", buffer[i])     

//或者您可以使用FILE * fp; for(int i = 0; i&lt; len; i ++)fprintf(fp,“%c”,buffer [i]);另一个好方法是使用fwrite。