StackIT
StackIT

Reputation: 1200

Read and Write structure to a binary file

I am trying to read and write structure to a binary file. This is what I have done.

#include <stdio.h>
#include <stdlib.h>
#pragma pack (1)
typedef struct employee
{
    char name[20];
    char empNo[10];
    int age;
    double salary;
}employee;

int main()
{
    FILE * pFile;
    long lSize;
    char * buffer;
    size_t result;
    employee e1 = {"Testing", "8208", 21, 1000.500};
    employee e2;

    pFile = fopen("myfile.bin" , "w+");
    fwrite(&e1, sizeof(e1), 1, pFile);
    buffer =(char*) calloc(1, sizeof(e1));
    if(buffer == NULL)
    {
        fputs("Memory error",stderr);
        exit(1);
    }

    rewind(pFile);
    // I know, I can read it to e2. But wanted to try to read to buffer.
    result = fread(buffer,sizeof(e2),1,pFile); 

    if(result != 1) 
    {
        fputs("Reading error",stderr); 
        exit(1);
    }
    sscanf(buffer,"%s %s %d %lf",e2.name,e2.empNo,&e2.age,&e2.salary);
    printf("%s %s %d %lf",e2.name,e2.empNo,e2.age,e2.salary);// Printing some garbage.
    fclose(pFile);
    free(buffer);
    return 0;
}

I know, that I can read directly to e2 variable using fread. But thought of trying to read it to buffer and then from the buffer read to e2. But not working. Dont know what mistake I am doing. I thought, it might be because of padding. So added #pragma pack. But no use.

Thanks in advance.

Upvotes: 1

Views: 591

Answers (3)

kunal
kunal

Reputation: 966

You dont have to use this

sscanf(buffer,"%s %s %d %lf",e2.name,e2.empNo,&e2.age,&e2.salary);

when you are using a struct as when you wrote to the file you wrote the struct into the file, therefore when reading back you should read the entire struct no parsing is required as it will read and assign everything accordingly.Use memcpy as suggested

memcpy(&e2,buffer,sizeof(e2));

Upvotes: 3

user1814023
user1814023

Reputation:

The problem is with your sscanf function.

7.21.6.7  The sscanf function is equivalent to fscanf, except that input is 
obtained from a string (specified by the argument s) rather than from a stream.

Standard says that, it will be read from string.

In your case, the char name[20]; is 20 bytes long and you are assigning "Testing" to it. What happened to remaining bytes? These remaining bytes are the garbage that you are getting. Also you are trying to read integer (which is 4 bytes in your case) and a double (which is 8 bytes) which are there as is in the buffer and they are not string.

What I feel is you are invoking undefined behavior here...

Upvotes: 0

Chinna
Chinna

Reputation: 4002

Problem is with your sscanf(). Use memcpy() instead of sscanf() like,

memcpy((char *)&e2,buffer,sizeof(e2));

It is working fine for me.

#include <stdio.h>
#include <stdlib.h>
#pragma pack (1)
typedef struct employee
{
    char name[20];
    char empNo[10];
    int age;
    double salary;
}employee;

int main()
{
    FILE * pFile;
    long lSize;
    char * buffer;
    size_t result;
    employee e1 = {"Testing", "8208", 21, 1000.500};
    employee e2;

    pFile = fopen("myfile.bin" , "w+");
    fwrite(&e1, sizeof(e1), 1, pFile);
    buffer =(char*) calloc(1, sizeof(e1));
    if(buffer == NULL)
    {
        fputs("Memory error",stderr);
        exit(1);
    }

    rewind(pFile);
    // I know, I can read it to e2. But wanted to try to read to buffer.
    result = fread(buffer,sizeof(e2),1,pFile);

    if(result != 1)
    {
        fputs("Reading error",stderr);
        exit(1);
    }
    memcpy((char *)&e2,buffer,sizeof(e2));
//    sscanf(buffer,"%s %s %d %lf",e2.name,e2.empNo,&e2.age,&e2.salary);
    printf("%s %s %d %lf",e2.name,e2.empNo,e2.age,e2.salary);// Printing some garbage.
    fclose(pFile);
    free(buffer);
    return 0;
} 

                                                                                                                                                          1,1           Top

Upvotes: 1

Related Questions