Reputation: 1218
I would like to store a struct in a file. I used this code:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int a;
short b;
char *ch;
} wrFile;
main()
{
FILE* fd=fopen("Result.txt","w+");
wrFile wf={12451,14,"result"};
fwrite(&wf,sizeof(wrFile),1,fd);
fclose(fd);
}
the resul that I obtained in Result.txt is:
£0^@^@^N^@^@^@^Z^G@^@^@^@^@^@
The question is why?
Upvotes: 1
Views: 5881
Reputation: 9819
w+ would be correct on linux, w+b is only needed on windows. But i guess the OP wanted to see something like "12451, 14,
result" in the file and is confused why he doesn't.
fwrite()
writes data directly in binary form, intended to be read by fread()
later, not intended to be readable by humans.
Your 12451
, as a 4 byte integer, in hex, is 00 00 30 a3
. As intel processors store data in little endian format, it would be written to the file as a3 30 00 00
. Which is exactly what we see - your first 4 characters are the pound sign, which has a hex code of A3, the next is the 0, (30
in hex), then 2 zero bytes. Same with the 14.
As your ch is a pointer, the pointer is written, not the string ("result") it points to.
Upvotes: 8
Reputation: 1271
As suggested by others you could use fprintf
, but if you wish to stick to fwrite
, you could store the values in a buffer, then write to file:
char cBuffer[1024]="";
...
snprintf(cBuffer, sizeof(cBuffer),"%d %hd %s",wf.a,wf.b,wf.ch);
fwrite(cBuffer,strlen(cBuffer),1,fd);
And don't forget to check if fd==NULL
after using fopen
Upvotes: 0
Reputation: 13446
The reason you get unexpected file output is because you write the structures into the file by their bit pattern.
A lot of problems in this case:
int
-typed field a
is written into file in binary mode;short
-typed field b
, and if your machine is 32-bit or 64-bit, there will be padding bits which are of course un-predictable (or un-printable);char*
-typed field ch
which is a pointer, or say it is a memory address and is only valid in this run of the program (if you run your program again, there could be other data occupying this chunk of memory).So IMHO, you should change your code like this:
fprintf(fd, "%d %hd %s\n", wf.a, wf.b, wf.ch);
And next time you read from the file, you should parse the data yourself.
Upvotes: 0
Reputation: 2068
That you're naming your output file Result.txt
suggests you expected human-readable ASCII text output.
That's not what fwrite
will give you if you hand it a buffer of binary data (your struct). In your case, you should open with wb+
to ensure your struct memory is correctly written. Also, I suggest not naming the file with a .txt
extension -- it is not incorrect, but it is sure to cause confusion with humans.
A good way to convince yourself that you're getting the right output is to fread
your data back into a struct and compare to the original. That would be a useful exercise for you. Hope this helps.
Upvotes: 0
Reputation: 6116
Instead of
FILE* fd=fopen("Result.txt","w+");
Use
FILE* fd=fopen("Result.txt","wb+");
to specify binary file mode.
The first way specifies the text mode, so everything you write is read as (usually) 1 byte char
, while what you really want to write is a binary data (stream of bytes arranged in some blocks). Also you can change the extension from .txt
to some other so not to get confused with text file.
Upvotes: 0
Reputation:
You are using normal fwrite
function which doesn't format the input. If you want to see proper data in the *.txt
file, use fprintf
.
Also, wrFile
will be padded with some extra bytes for alignment purpose which will also be written into file if you use fwrite
function.
Instead use
fprintf(fd, "%d, %d, %s", wf.a, wf.b, wf.ch);
Upvotes: 0
Reputation: 5796
You may have a misunderstanding of what fwrite actually does. After writing your struct to the file, you can't expect to read it back using a text editor. If you wanted that, you would have to use
fprintf(fd, "%i, %i, %s\n", wf.a, wf.b, wf.ch);
because fwrite will write the struct to file to be machine readable, that is in its most compact binary form, which your text editor does not understand.
Also, if you frwite a char* to a file, you just write the pointer, and not the contents.
Upvotes: 1
Reputation: 6787
When you call fwrite(&wf,sizeof(wrFile),1,fd);
, what you are writing is the actual bytes in memory to the file. In other words, you're writing the 'raw' data into the file instead of the textual representation.
Consider using fprintf
instead like such
fprintf(&wf, "a=%d\n", wf.a);
fprintf(&wf, "b=%d\n", wf.b);
fprintf(&wf, "ch=%s\n", wf.ch);
Given your code above, this would output the following to the file pointed to by wf
:
a=12451
b=14
ch=result
hope that helps.
Upvotes: 0