为什么fwrite会写奇怪的东西?

时间:2015-10-29 01:51:39

标签: c printf byte fwrite

所以我得到的是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

int main()
{

FILE *fin;
struct STR {
    float d;
    int x;
} testing;

testing.d = 11.12;
testing.x = 31121;


    fin = fopen("output.txt", "w");
    //fprintf(fin,"%7.4f %7d\n",testing.d,testing.x);
    fwrite(&testing, sizeof(struct STR),1,fin);
    fclose(fin);
    return 0;
}

那么当我编译并运行时会发生什么?我明白了:

"…ë1A‘y  "

当我发表评论fwrite并使用fprintf时,我明白这一点:

"11.1200   31121"

有人可以向我解释一下吗?我尝试在Windows和Linux上运行它,两次输出都很模糊。

另外,我想我们在讨论这个主题时,文本文件的大小如何用&#34; 11.1200 31121&#34;是16个字节?我认为整数(在32位机器上)每个是4个字节?它是16个字节,因为txt文件中总共有16个字符?

谢谢

2 个答案:

答案 0 :(得分:0)

您正在将文件作为文本文件打开,但您正在编写二进制数据,它不是人类可读的。要正确阅读,您需要fread()。而是fprintf()可以检查文本。

所以

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

struct STR {
    float d;
    int x;
} testing;

int main()
{

    FILE *file;
    testing.d = 11.12;
    testing.x = 31121;


    file = fopen("output.txt", "wb");
    if (file != NULL)
    {
        fwrite(&testing, sizeof(struct STR), 1, file);
        fclose(file);
    }

    file = fopen("output.txt", "rb");
    if ((file != NULL) && (fread(&testing, sizeof(struct STR), 1, file) == 1))
    {
        fprintf(stdout, "%f -- %d\n", testing.d, testing.x);
        fclose(file);
    }

    return 0;
}

应该说清楚。

答案 1 :(得分:0)

正如iharob所说,你正在编写的二进制数据在当前语言环境中被解释为无意义的字符,而不是人类可读的ASCII。此外,编译器为结构分配16个字节的原因是填充。编译器填充到16个字节的原因是你的CPU有特殊的指令,当它们的大小是2的小功率时,可以更有效地索引结构数组。

如果您确实希望以便携式二进制格式序列化数据,或通过网络传输数据,则应使用精确宽度类型,例如int32_t而不是int(具有是16,32或64位,可能有其他宽度)并且还转换为特定的字节序,而不是本机字节顺序恰好是什么。经典的解决方案是htonl()。另外,分别写出每个字段以避免填充问题,或者使用编译器扩展来打包结构并关闭填充。