3

我需要使用 C 的 I/O 函数将数据写入二进制文件。以下代码导致运行时异常:


#include "stdio.h"

int main(int argc,char* argv[]) {
    FILE *fp = fopen("path_to_file.bin","wb");
    if(fp == NULL) {
        printf("error creating file");
        return -1;
    }
    int val = 4;
    fwrite((const void*)val,sizeof(int),1,fp);
    fclose(fp);
    return 0;
}

代码在 fwrite 处死掉。你能看出我做错了什么吗?显然,我正在尝试访问 0x0000004 或类似的数据。

谢谢 !

4

6 回答 6

25

我认为尼尔的答案可以改进。我意识到它已经被接受了,所以这只是为了展示一些对比(这就是为什么我不只是编辑他的)。

fwrite(&val, sizeof val, 1, fp);

两个改进:

  • 没有指针转换,因为它在 C 中不是必需的并且可以隐藏错误。
  • 直接在对象上使用sizeof,因为这是您传递指针的对象。对我来说很有意义,并且比重复自己和使用类型名称更安全。
于 2009-04-21T11:29:04.063 回答
18
 fwrite((const void*)val,sizeof(int),1,fp);

应该:

 fwrite((const void*) & val,sizeof(int),1,fp);

顺便说一句,如果您不使用演员表,您将收到一条合理的错误消息。C(和 C++)程序员往往比他们应该使用的更频繁地使用强制转换 - 一个好的经验法则是“如果它需要强制转换,它可能是错误的”。

于 2009-04-21T11:22:12.330 回答
5

添加到尼尔的答案:当您在同一平台上读取和写入文件时,这有效。如果你在不同字节序的平台上读/写,事情会变得很奇怪。

于 2009-04-21T11:26:18.327 回答
0
#include "stdio.h"

int main(int argc,char* argv[]) {
    FILE *fp = fopen("path_to_file.bin","wb");
    if(fp == NULL) {
        printf("error creating file");
        return -1;
    }
    int val = 4;
    fwrite((const void*)val,sizeof(int),1,fp);

您应该提供一个地址而不是整数本身。

另外,您不应该以这种方式使用整数:

  1. 不同计算机上的字节序可能不同(如前所述)
  2. 它的大小可能不同。在非常旧的计算机上,它可能是 1 或 2 个字节。在大多数现代设备上,它将是 4,但也可能是 8(一些 64 位计算机)。在一些奇怪的架构上,它甚至可能是 36 位。int32_t val = 4; fwrite((const void *)val, 4, 1, fp)应该解决问题。

您可能认为您的软件永远不需要移植。好吧 - 许多设计师(软件和硬件)做出了类似的假设。有时不制作它们的成本太高 - 但在这种情况下,只需进行一些额外的检查。

    fclose(fp);
    return 0;
}
于 2009-04-21T18:14:37.707 回答
0

我也遇到过这种问题。所以这是我的解决方案。

fwrite(val, sizeof(val[0], sizeof(val)/sizeof(val[0]), fp);

于 2016-11-09T04:02:38.440 回答
0

显然,我正在尝试访问 0x0000004 或类似的数据。

int val = 4

这就是问题所在。fwrite被设计用于处理字符串,因此它的第一个输入是一个指针,一个字符串在内存中的位置。您val直接传递 (4) 的值而不是valto的地址fwrite;但是,0x00000004 处的内存不是有效的程序内存,因此会出现错误。

要解决此问题,请更改此:

fwrite((const void*)val,sizeof(int),1,fp);

进入这个:

fwrite((const void*)&val, sizeof(int), 1, fp);

“&”运算符表示 的位置val。这将是内存中的有效地址。

于 2018-02-24T01:46:11.323 回答