Kallel Omar
Kallel Omar

Reputation: 1218

Store a struct in a file using fwrite

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

Answers (8)

Guntram Blohm
Guntram Blohm

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

H_squared
H_squared

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

Summer_More_More_Tea
Summer_More_More_Tea

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:

  1. the int-typed field a is written into file in binary mode;
  2. there is a 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);
  3. you have a 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

Darren Stone
Darren Stone

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

0xF1
0xF1

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

user1814023
user1814023

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

Andreas Grapentin
Andreas Grapentin

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

txtechhelp
txtechhelp

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

Related Questions