c语言fwrite与fread函数读取写入结构体到文件问题

问题遇到的现象和发生背景

c语言使用两个cpp分别执行将带"

字符指针成员"的结构体写入文件,从文件中读入结构体。若将两个cpp文件的代码在同一个cpp文件下运行可以正确读取"结构体的成员字符指针",但先执行存入结构体cpp文件后再执行读入结构体cpp文件读入"结构体字符指针成员"会报错。

问题相关代码,请勿粘贴截图

存入文件代码:
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
typedef struct seat {
char *a;
}node,tnode;
int main() {
FILE
fc = fopen("C:\Users\24345\Desktop\航空管理系统\flight.rec", "wb+");
tnode t = new node;
t->a = new char[20];
strcpy(t->a, "wori");
fwrite(t, sizeof(node), 1, fc);
fwrite(t->a, sizeof(t->a), 1, fc);
fclose(fc);
return 0;}

读入文件代码:
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
typedef struct seat {
char a;
}node,tnode;
FILE
fp = fopen("C:\Users\24345\Desktop\航空管理系统\flight.rec", "rb+");
tnode g = new node;
g->a = new char[20];
fread(g, sizeof(node), 1, fp);
fread(g->a,sizeof(g->a),1,fp);
printf("%s", g->a);
fclose(fp);
return 0;}
//两段代码同时运行的代码
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
typedef struct seat {
char
a;
}node, * tnode;
int main() {
FILE* fc = fopen("C:\Users\24345\Desktop\航空管理系统\flight.rec", "wb+");
tnode t = new node;
t->a = new char[20];
strcpy(t->a, "wori");
fwrite(t, sizeof(node), 1, fc);
fwrite(t->a, sizeof(t->a), 1, fc);
fclose(fc);

FILE* fp = fopen("C:\\Users\\24345\\Desktop\\航空管理系统\\flight.rec", "rb+");
tnode g = new node;
g->a = new char[20];
fread(g, sizeof(node), 1, fp);
fread(g->a, sizeof(g->a), 1, fp);
printf("%s", g->a);
fclose(fp);
return 0;

}

运行结果及报错内容

分别运行的结果:
分别运行代码:

img

img


同时运行的代码:

img

我的解答思路和尝试过的方法
我想要达到的结果

需要将存入文件代码和读入文件代码在两个不同cpp文件中分别执行,通过读入文件代码得到存入文件代码保存在文件中的结构体。结构体的"字符指针"能返回正确的字符串。

sizeof(g->a)改成20试试

字符指针和字符数组是有区别的,虽然在c具体使用中有时可以互相替代使用,但作为数据结构需要持久化存储时(即存储到文件中去),其实差异是很大的。
一般来说,在结构体中字符数组是可以直接存储的,而字符指针却不能,因为数组在结构体中是可以固定大小的,也方便解析,而单纯的指针,因为具体的信息并不是直接放置在结构体中,这个指针信息脱离了运行环境也是无意义的,所以一般结构体中存在单纯的字符指针时,是不会直接存储到文件中的。即使存储了,恢复时数据也是没有意义的。

如果真正有结构体存在单纯指针类信息,需要同步持久化,都需要专门的方法或者结构来写和读取(解析),说穿了,就是存储的结构化数据需要能完整的保留原始内存中的组织信息,又能在恢复时重新构建出来,比如利用json或者xml来组织数据信息。

修改见注释,供参考:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct seat {
    char* a;
}node,* tnode;
int main() {
    FILE* fc = fopen("D:\\flight.rec", "wb+");
    //fopen("C:\Users\24345\Desktop\航空管理系统\flight.rec", "wb+");
    tnode t = new node;
    t->a = new char[20];
    strcpy(t->a, "wori");
    //fwrite(t, sizeof(node), 1, fc);// t 是指向一个结构体指针,是一个地址值,把它写入文件没有意义。
    fwrite(t->a, sizeof(t->a), 1, fc);
    fclose(fc);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct seat {
    char* a;
}node, * tnode;
int main() {
    FILE* fp = fopen("D:\\flight.rec", "rb+");
    //fopen("C:\Users\24345\Desktop\航空管理系统\flight.rec", "rb+");
    tnode g = new node;
    g->a = new char[20];
    //fread(g, sizeof(node), 1, fp); // g 是新 new 空间地址,把文件里保存t的地址值读出赋值给 g ?
    //fread(g->a, sizeof(g->a), 1, fp); //经上句赋值,此处g->a 不是新 new 的空间地址,就出错了。
    fgets(g->a, sizeof(g->a), fp);
    printf("%s", g->a);
    fclose(fp);
    return 0;
}