lost_in_the_source
lost_in_the_source

Reputation: 11237

fwrite prints garbage, fread reads garbage structures

I was testing out binary file i/o. So, to practice I made a small program:

main.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "person.h"

int main()
{
    struct person me;
    struct person cpy_me;
    FILE *dataWrite, *dataRead;

    strcpy(me.fname, "john");
    strcpy(me.lname, "smith");
    me.age = 12;

    printf("%s %s %d\n", me.fname, me.lname, me.age);

    dataWrite = fopen("people.bin", "wb");
    if (fwrite(&me, sizeof( struct person), 1, dataWrite) != 1)
        fprintf(stderr, "Error!\n");
    printf("Wrote to the file\n");

    dataRead = fopen("people.bin", "rb");

    fread(&cpy_me, sizeof(struct person), 1, dataRead);
    printf("%s->Fname\n", cpy_me.fname);
    printf("%s->Lname\n", cpy_me.lname);
    printf("%d->Age\n", cpy_me.age);

    fclose(dataWrite);
    fclose(dataRead);

    return 0;
}

person.h:

#ifndef PERSON_H_INCLUDED
#define PERSON_H_INCLUDED

#define   MAXFIRST    10
#define   MAXLAST     20

struct person
{
    char lname[MAXLAST], fname[MAXFIRST];
    int age;
};
#endif // PERSON_H_INCLUDED

This is what appeared in the file people.bin:

smith ÿÿb¸tÄ[½tà@ john @ à@                                       

When I read displayed the results of fread, I got:

enter image description here

I know that in binary files, it doesn't display it in a human readable form, but is it supposed to look like this? I don't think so, because the age isn't even visible, and fread is showing that it read garbage.

Upvotes: 2

Views: 478

Answers (1)

Steven Golden
Steven Golden

Reputation: 151

This code snippet has two separate problems: First, as BLUEPIXY already commented, you need to either close and reopen, or rewind the file, before reading it in again. Otherwise your fread() fails, and since this is not checked for errors in your program, you won't notice until you try to print the strings inside cpy_me, which have remained uninitialized.

This gets to problem number two: make sure to initialize struct me to zeros, e.g. by doing struct person me = {"", "", 0}; This should take care of the garbage you see in your binary file. Structs in C are not automatically initialized unless they are globals or you explicitly tell the compiler to do so.

As an aside: Note that doing binary I/O like this is non-portable, since the structs may have a different memory layout on different architectures (to see this, try recompiling in 32 and 64-bit mode and compare the binary files your program generates).

Upvotes: 2

Related Questions