C语言:从二进制文件读取空终止字符串失败的修复求助
问题分析与修复
你的代码核心问题出在字符串写入文件的逻辑:obj->y是字符指针,&obj->y取的是指针变量本身的内存地址,你用fwrite写入的是这个指针地址的值,而非"Hello"字符串的实际内容。读取时自然无法正确解析,导致输出乱码。
另外,文件操作建议使用二进制模式("wb"/"rb"),避免文本模式下的换行符自动转换等潜在问题。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> struct A { int x; char *y; }; #define INITIAL_BUFFER_LENGTH 10 char *read_string_from_file(FILE *handle) { int string_capacity = INITIAL_BUFFER_LENGTH; char *string = malloc(string_capacity); if (!string) { // 增加内存分配失败判断 perror("malloc failed"); exit(EXIT_FAILURE); } int count = 0; int c; // 用int存fgetc返回值,避免EOF被误判为有效字符 while ((c = fgetc(handle)) != '\0' && c != EOF) { string[count] = (char)c; count++; if (count == string_capacity) { string_capacity *= 2; char *temp = realloc(string, string_capacity); if (!temp) { // 增加realloc失败判断 perror("realloc failed"); free(string); exit(EXIT_FAILURE); } string = temp; } } string[count] = '\0'; return string; } int main(void) { struct A *obj = malloc(sizeof(struct A)); if (!obj) { // 增加内存分配失败判断 perror("malloc failed"); exit(EXIT_FAILURE); } obj->x = 228; obj->y = "Hell"; printf("x == %i\n", obj->x); printf("y == %s\n", obj->y); // 以二进制模式写入文件 FILE *file = fopen("f.txt", "wb"); if (!file) { // 增加文件打开失败判断 perror("fopen write failed"); free(obj); exit(EXIT_FAILURE); } fwrite(&obj->x, sizeof(obj->x), 1, file); // 写入字符串实际内容,而非指针地址 fwrite(obj->y, strlen(obj->y) + 1, 1, file); fclose(file); obj->x = 0; obj->y = NULL; // 以二进制模式读取文件 file = fopen("f.txt", "rb"); if (!file) { perror("fopen read failed"); free(obj); exit(EXIT_FAILURE); } fread(&obj->x, sizeof(obj->x), 1, file); obj->y = read_string_from_file(file); printf("x == %i\n", obj->x); // 输出228 printf("y == %s\n", obj->y); // 输出Hell // 释放资源 free(obj->y); free(obj); fclose(file); return 0; }
关键修复点
- 写入字符串时,将
fwrite(&obj->y, ...)改为fwrite(obj->y, ...),写入字符串的实际内容而非指针地址 - 文件打开使用二进制模式
"wb"和"rb",避免文本模式的格式转换干扰 - 新增内存分配、文件打开的错误检查,提升代码健壮性
- 修正
read_string_from_file中用int存储fgetc返回值的问题,避免EOF被误判为有效字符
内容的提问来源于stack exchange,提问作者Emily Grace Seville
相关产品推荐
相关产品推荐

