Problem writing int to binary file in C
Solution 1
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".
Solution 2
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.
- 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.
Solution 3
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.
Related videos on Youtube
MarkD
Updated on February 24, 2020Comments
-
MarkD about 4 years
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.
Thanks !
-
dirkgently about 15 years+1 Good points, both. Moral of the story: prefer as little casts and use sizeof judiciously.
-
MarkD about 15 yearsCan you please explain why the cast isn't necessary? I'm not a C programmer ... and I would like to understand as much as possible of it's "magic".
-
Ferruccio about 15 yearsfwrite() expects a void* as its first argument. Any pointer type can be used where a void* is expected without casting. void* effectively says "I need a pointer, I don't care what type it points to".
-
quinmars about 15 yearsNot only endianness, also the size may vary.
-
Juan Techera about 15 yearsC is soo not multi platform, in the file writing/reading you need to make a implementation for each platform most times, different end of line markers and things like that become a nightmare when dealing with file writing/reading across platforms (kindda off topic anyway :P)
-
Greg about 10 years+ another 1 for that rule. i have it on a sticky note on my monitor.