English 中文(简体)
在C语言中写整数到二进制文件的问题
原标题:
  • 时间:2009-04-21 11:19:27
  •  标签:

I need to write data to a binary file using C s I/O functions. The following code causes a runtime exception :


#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;
}

The code dies at the fwrite. Can you spot what I m doing wrong? Apparently, I m, trying to access data at 0x0000004 or something like that.

谢谢!

最佳回答
 fwrite((const void*)val,sizeof(int),1,fp);

应该是:

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

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

问题回答

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

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

Two improvements:

  • No pointer casting, since it s not necessary in C and can hide errors.
  • Use sizeof directly on the object, since that is what you re passing a pointer to. Makes a lot of sense to me, and is safer than repeating yourself and using the type name.

Adding to Neil s answer: this works when you are reading and writing the file on the same platform. Things can become weird if you are reading/writing across platforms with different endianness.

#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);

You should supply an address not integer itself.

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

  1. It may differ in endianess on different computers (as mentioned)
  2. It may differ in size. On really old computers it may be 1 or 2 bytes. On most modern it will be 4 but it may be 8 as well (some 64-bit computers). On some strange architectures it may be even 36 bits. int32_t val = 4; fwrite((const void *)val, 4, 1, fp) should solve the problem.

You may think that your software will never need to be ported. Well - many designers (software and hardware) made similar assumptions. Sometimes it is too costly to not make them - but in this case it is just a matter of few additional checks.

    fclose(fp);
    return 0;
}

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

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

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

int val = 4

这就是问题所在。fwrite 的设计是用来处理字符串的,因此它的第一个输入参数是指针,即字符串在内存中的位置。你传递的是 val 的值 (4),而不是它的地址给 fwrite;然而,内存地址 0x00000004 并不是有效的程序内存,因此会报错。

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

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

Into this:

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

"&" 运算符指示了 val 的内存地址。这将是一个有效的内存地址。





相关问题
热门标签