使用C中的fread()从二进制文件读取时的奇怪值

时间:2013-06-16 16:10:52

标签: c linux fwrite fread

我有一个我无法解决的问题......

我使用fwriteint值(来自struct的其他值)写入我使用fopen(file, "wb");

这很好用,当我查看文件的内容时,我可以看到{已写入“HEX的{​​{1}}值(以及所有其他值)

接下来,我尝试读取该文件。因此,我使用int打开文件,然后使用fopen(file, "rb");开始阅读。第一个fread值正确读取(例如7)和其后的所有其他值 - 属于我编写的第一个int

然后我尝试阅读下一个struct,当我尝试读取第一个struct值时,我收到一个非常奇怪的数字(例如1140850688)但它应该是39而不是。

所以问题是:为什么会这样?我该如何解决?

我的int看起来像这样:

struct

struct a { int a1; char* a2; struct b* a3; unsigned char a4; int a5; char* a6; } 电话看起来像这样:fread

编辑:

fread(&(tmpA->a1), sizeof(int), 1, file);部分:

fwrite

fwrite(&(tmpA->a1), sizeof(int), 1, file); fwrite(tmpA->a2, sizeof(char), strlen(tmpA->a2), file); fwrite(tmpA->a3, sizeof(struct b), 1, file); fwrite(&(tmpA->a4), sizeof(unsigned char), 1, file); fwrite(&(tmpA->a5), sizeof(int), 1, file); fwrite(tmpA->a6, sizeof(char), strlen(tmpA->a6), file); 几乎相同。

2 个答案:

答案 0 :(得分:3)

如果你从一个文件中写了一个struct,你应该读一个struct;试图阅读int是行不通的。但是,如果有的话,很少有两个写出包含指针的二进制struct。您应该将它们设置为固定大小的数组,或者将它们与struct分开序列化。

编辑:(响应发布的代码)很可能问题与在fwrite的第二次调用中写入未知数量的字符有关。序列化C字符串时,您应该在写入字符之前写出字符数,这样当您阅读时,您知道要分配多少字符并回读:

int len = strlen(tmpA->a2);
fwrite(&len, sizeof(int), 1, file);    
fwrite(tmpA->a2, sizeof(char), len, file);
...
fread(&(tmpA->a1), sizeof(int), 1, file);
tmpA->a2 = malloc(tmpA->a1+1);
fread(tmpA->a2, sizeof(char), tmpA->a1, file);
tmpA->a2[tmpA->a1] = '\0';

答案 1 :(得分:2)

我怀疑你的问题就在这一行

fwrite(tmpA->a3, sizeof(struct b), 1, file);

您正在撰写struct。这个结构将有填充字节,按this wikipedia article,它将抵消其余的数据。您可能必须想出一种更好的方法来将该结构写入内存。 This page提供了其他说明。

您可以通过检查a4是否具有您期望的值,或通过比较整个结构的大小与其成员大小的总和来检查这是否确实是问题。

此外,这些线条看起来很危险:

fwrite(tmpA->a2, sizeof(char), strlen(tmpA->a2), file);
fwrite(tmpA->a6, sizeof(char), strlen(tmpA->a6), file);

他们说打印的字符串长度可能因存储的数据而异。 strlen将为您提供字符串的长度而不计算终止\0,因此在您编写字符串后,没有好的方法可以知道字符串的结束位置。我无法想象你打算如何重新读取字符串。