You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:45:47