为何无法用fwrite函数将字符串字面量存入TXT文件?代码问题咨询
结构体字符串写入文件的问题解答
核心问题:能否用fwrite存储字符串字面量?
可以,但不能直接写入字符串指针,必须写入字符串的实际字节内容。fwrite是按二进制写入指定内存块的内容,如果写的是char*指针,只会把指针的地址值(比如0x7ffe1234)写入文件,而不是字符串本身。
当前代码的问题分析
你的代码无法正确写入名字到文件,有两个关键原因:
1. 所有结构体的name指针指向同一个局部数组
char nam[50]; // ... s[i].name = nam;
循环中每次输入名字都会覆盖nam数组的内容,而且所有student结构体的name指针都指向这个数组的地址。这会导致:
- 循环结束后,所有结构体的
name都指向最后一次输入的名字; - 当
create函数执行完毕,局部数组nam被销毁,这些name指针会变成野指针,访问时会触发未定义行为。
2. fwrite写入的是指针地址而非字符串内容
fwrite(&s[i], sizeof(student), 1, fp);
student结构体中的name是char*类型,存储的是字符串的内存地址。用fwrite写入整个结构体时,只会把这个地址值写入文件,而不是地址指向的字符串内容。所以打开ask.txt看到的是乱码或十六进制地址,不是实际的名字。
解决办法
根据需求,有两种常见的修正方式:
方式一:将结构体的name改为固定大小字符数组
把char* name改成char name[50],让结构体直接存储字符串内容,这样fwrite整个结构体就能把名字写入文件:
typedef struct student { int rno; char name[50]; // 用固定数组存储字符串 } student; void create(){ student *s; FILE *fp; int n, i; printf("Enter number: "); scanf("%d", &n); s = (student*)calloc(n, sizeof(student)); fp = fopen("ask.txt", "w"); for (i=0; i < n; i++){ printf("Enter rollno: "); scanf("%d", &s[i].rno); fflush(stdin); printf("Enter name: "); scanf("%s", s[i].name); // 直接写入结构体的数组 fwrite(&s[i], sizeof(student), 1, fp); } fclose(fp); free(s); // 记得释放堆内存 }
这种方式简单直接,适合字符串长度可控的场景。
方式二:保留char*指针,分开写入字符串内容
如果必须使用char*指针,需要手动写入字符串的长度和内容,而不是直接写结构体:
typedef struct student { int rno; char *name; } student; void create(){ student *s; FILE *fp; int n, i; char nam[50]; printf("Enter number: "); scanf("%d", &n); s = (student*)calloc(n, sizeof(student)); fp = fopen("ask.txt", "w"); for (i=0; i < n; i++){ printf("Enter rollno: "); scanf("%d", &s[i].rno); fflush(stdin); printf("Enter name: "); scanf("%s", nam); s[i].name = strdup(nam); // 复制字符串到堆内存,避免覆盖 // 分步写入:先写学号,再写字符串长度,最后写字符串内容 fwrite(&s[i].rno, sizeof(int), 1, fp); size_t name_len = strlen(s[i].name) + 1; // +1包含字符串终止符'\0' fwrite(&name_len, sizeof(size_t), 1, fp); fwrite(s[i].name, sizeof(char), name_len, fp); } fclose(fp); // 记得释放每个name的堆内存 for (i=0; i < n; i++){ free(s[i].name); } free(s); }
这种方式适合字符串长度不固定的场景,但读取文件时也要对应分步读取:先读学号,再读长度,分配内存后读字符串内容。
内容的提问来源于stack exchange,提问作者Leon Loo
相关产品推荐
相关产品推荐

