读写二进制文件的结构

时间:2013-12-10 06:08:31

标签: c file

我正在尝试读取和写入二进制文件的结构。这就是我所做的。

#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;
}

我知道,我可以使用e2直接阅读fread变量。但是想到尝试将其读取到buffer,然后从buffer读取到e2。但不行。不知道我在做什么错。我想,这可能是因为填充。所以添加了#pragma pack。但没用。

提前致谢。

3 个答案:

答案 0 :(得分:3)

你不必使用这个

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

当你使用结构时,就像你写入文件一样,你将结构写入文件中,因此在阅读时你应该读取整个结构,不需要解析,因为它会读取并相应地分配所有内容。使用memcpy作为建议

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

答案 1 :(得分:1)

问题在于您的sscanf()。使用memcpy()代替sscanf()

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

这对我来说很好。

#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

答案 2 :(得分:0)

问题在于您的sscanf功能。

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.

标准说,它将从字符串中读取。

在您的情况下,char name[20];长度为20个字节,您要为其分配"Testing"。剩下的字节发生了什么?这些剩余的字节是你得到的垃圾。 您还试图读取integer(在您的情况下是4个字节)和double(8个字节),它们在buffer中并且它们不是字符串

我觉得你在这里调用未定义的行为......