简体   繁体   English

将int写入C中的二进制文件时出现问题

[英]Problem writing int to binary file in C

I need to write data to a binary file using C's I/O functions. 我需要使用C的I / O函数将数据写入二进制文件。 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. 该代码死于fwrite。 Can you spot what I'm doing wrong? 你能发现我在做什么错吗? Apparently, I'm, trying to access data at 0x0000004 or something like that. 显然,我正在尝试访问0x0000004或类似的数据。

Thanks ! 谢谢 !

I think Neil's answer can be improved upon. 我认为尼尔的答案可以改善。 I realize it's already accepted, so this is just to show some contrast (which is why I didn't just edit his). 我知道它已经被接受了,所以这只是为了显示一些对比(这就是为什么我不只是编辑他的原因)。

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

Two improvements: 两项改进:

  • No pointer casting, since it's not necessary in C and can hide errors. 没有指针强制转换,因为它在C语言中是不必要的,并且可以隐藏错误。
  • Use sizeof directly on the object, since that is what you're passing a pointer to. 直接在对象上使用sizeof ,因为这就是您要传递的指针。 Makes a lot of sense to me, and is safer than repeating yourself and using the type name. 对我来说很有意义,并且比重复自己和使用类型名称更安全。
 fwrite((const void*)val,sizeof(int),1,fp);

should be: 应该:

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

BTW, if you don't use the cast, you will get a sensible error message. 顺便说一句,如果您不使用强制转换,则会收到一条明智的错误消息。 Casts tend to be used by C (and C++) programmers far more often than they should be - a good rule of thumb is "if it needs a cast, it's probably wrong". C(和C ++)程序员使用Cast的次数往往比实际使用的次数多得多-一个好的经验法则是“如果需要Cast,那可能是错误的”。

Adding to Neil's answer: this works when you are reading and writing the file on the same platform. 尼尔(Neil)的答案:当您在同一平台上读写文件时,此方法有效。 Things can become weird if you are reading/writing across platforms with different endianness. 如果您在具有不同字节序的平台上进行读取/写入,事情可能会变得很奇怪。

I also faced this kind of problem. 我也遇到这种问题。 So this is my solution. 这就是我的解决方案。

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

Apparently, I'm, trying to access data at 0x0000004 or something like that. 显然,我正在尝试访问0x0000004或类似的数据。

int val = 4

There's the issue. 有问题。 fwrite is designed to work with strings, and as such its first input is a pointer, the location of a string in memory. fwrite设计为可用于字符串,因此,它的第一个输入是指针,即字符串在内存中的位置。 You are passing the value of val directly (4) rather than the address of val to fwrite ; 您直接将val的值(4)而不是val的地址传递给fwrite however, the memory at 0x00000004 is not valid program memory and thus an error is given. 但是,0x00000004处的存储器不是有效的程序存储器,因此会出现错误。

To fix this, change this: 要解决此问题,请更改以下内容:

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

Into this: 变成这个:

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

The "&" operator indicates the location of val . “&”运算符指示val的位置。 This would be a valid address in memory. 这将是内存中的有效地址。

#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. 您应该提供一个非整数的地址。

Additionaly you should not use the integer in such way: 另外,您不应以这种方式使用整数:

  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. 在非常老的计算机上,它可能是1或2个字节。 On most modern it will be 4 but it may be 8 as well (some 64-bit computers). 在大多数现代计算机上,它是4,但也可能是8(某些64位计算机)。 On some strange architectures it may be even 36 bits. 在某些奇怪的体系结构上,它甚至可能是36位。 int32_t val = 4; fwrite((const void *)val, 4, 1, fp) int32_t val = 4; fwrite((const void *)val, 4, 1, fp) should solve the problem. int32_t val = 4; fwrite((const void *)val, 4, 1, fp)应该可以解决问题。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM