从文件中读取struct对象并指向使用void *指针读取的对象

时间:2013-10-09 09:37:01

标签: c pointers file-io void-pointers

我的程序中有以下四个结构

struct SType{
    int type;//struct type
};

struct S1{
};

struct S2{
};

struct S3{
};

我使用以下代码将这些结构的状态保存在文件中:

  

void store(struct SType s1,void * s){

//open file and stuff
//s points to either one of the last three structs
fwrite(&s1,sizeof(s1),1,file);  fwrite(s, size, 1, file);
//structs are always saved in the file in pairs of SType and either one of the last three structs 
}

现在,当我尝试使用以下代码从文件中检索该对的第二个结构时,我得到分段错误。那么如何使用fread()?

来检索一个任意结构类型的对象
void read(){
void *record;
//read struct SType object from the file 
//now read the second struct of the pair   
fread(record,size,1,file);
}

2 个答案:

答案 0 :(得分:3)

你必须读入有效的内存。 void表示“我不知道”,系统不能也不会为你猜出这个值! 你拥有的是:

void read(){
void *record;// This pointer currently is a random value - this will cause a fault when you try and copy data into it by calling:
fread(record,size,1,file);
}

应该是:

void read(){
void *record;
len = ?; // Your program needs to know this. You must know which structure it is somehow if you are to cast it later. Therefore you should know its size.
record = malloc(len); // Where len has been previously found to be AT LEAST big enough to read into
fread(record,size,1,file);
}

如你所说,你的代码不是伪代码,那么也会在你的结构中添加一些东西,这样它们就不会是空的。一旦你阅读了它,最好对结构做一些事情,例如从你的恐惧中返回虚空*。

希望有所帮助。

答案 1 :(得分:1)

你读取了未初始化指针的记录,我想你应该首先分配内存。

void *record = maloc( size )

不要忘记自由......

我建议您使用联盟吗?

您的类型定义如下所示:

struct SType{
    int type;//struct type
};
struct S1{
};

struct S2{
};

struct S3{
};

union S{
    S1 s1;
    S2 s2;
    S3 s3;
};

现在可以这样读写:

SType stype;
S s;

fread(&stype,sizeof(stype),1,file);
size = ???  //get according to type
fread(&s,size,1,file); 
// your data will be stored according to type in s.s1, s.s2 or s.s3   

size = ???  //get according to type
fwrite(&stype,sizeof(stype),1,file);
fwrite(&s,size,1,file);

下一阶段,是将Type与其余部分统一起来:

struct S{
    int type;//struct type
    union {
        S1 s1;
        S2 s2;
        S3 s3;
    }s;
};
/* in case you don't care about loosing file space, 
   you can read\write all in a single operation like this:
 */ 
S s;
fread(&s,sizeof(s),1,file); 
// now according to the type you take s.s.s1, s.s.s2 or s.s.s3.   
fwrite(&s,sizeof(s),1,file);

/* if you do care about loosing file space, you work like before */
S s;
fread(&s.type,sizeof(int),1,file);
size = ??? //get according to type
fread(&s.s,size,1,file); 
// as before, you take s.s.s1, s.s.s2 or s.s.s3.   
size = ???  //get according to type
fwrite(&s.type,sizeof(int),1,file);
fwrite(&s.s,size,1,file);