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

文件已有内容时fputs函数失效的问题排查求助

问题排查与修复方案

核心问题及修复

1. Save函数未初始化目标字符串导致崩溃

Save函数中的fullString是局部字符数组,默认未初始化,内存中为随机垃圾数据。strcat要求目标字符串必须以'\0'结尾才能正确拼接,空文件时可能巧合内存初始为0,但非空文件时垃圾数据中无'\0',strcat会越界访问内存,直接导致程序崩溃。
修复:初始化fullString为空字符串

void Save(struct SEED arrayToSave[], int size) {
  FILE* myFile = fopen("Catalogue.txt", "w");
  char fullString[1000000] = {0}; // 初始化空字符串

  for(int i = 0; i < size; i++) {
    struct SEED currentStruct = arrayToSave[i];
    char stringToAdd[1000];
    sprintf(stringToAdd, "%d %s %s %f %f\n", currentStruct.index, currentStruct.type, currentStruct.name, currentStruct.mass, currentStruct.price);
    strcat(fullString, stringToAdd);
  }
  printf("%s\n", fullString);
  fputs(fullString, myFile);
  fclose(myFile);
}

2. GetText函数未添加字符串终止符

GetText从文件读取字符到text数组后,未手动添加'\0',导致strlen、strtok等字符串函数无法识别字符串结束位置,会读取数组外的垃圾数据,引发后续numberOfItems计算错误、字符串分割异常。
修复:读取完成后添加终止符,同时增加文件打开失败判断和数组越界防护

void GetText() {
  FILE* catalogueFile;
  char ch;
  int counter = 0;

  catalogueFile = fopen(path, "r");
  if (!catalogueFile) return; // 处理文件打开失败情况
  while((ch = fgetc(catalogueFile)) != EOF && counter < 999999) { // 防止数组越界
    text[counter] = ch;
    counter++;
  }
  text[counter] = '\0'; // 添加字符串终止符
  fclose(catalogueFile);
}

3. GetArrayOfStructs内存分配错误

代码中malloc(numberOfItems * sizeof(arrayOfStructs))里的arrayOfStructs是指针,sizeof得到的是指针大小(通常4/8字节),而非struct SEED的实际大小,导致分配内存远小于需求,结构体数组越界写入破坏内存。
修复:改为按结构体大小分配

struct SEED* arrayOfStructs = malloc(numberOfItems * sizeof(struct SEED));

4. AddNew函数错误传参

GetArrayOfStructs是无参函数,但AddNew中调用时传了path参数,不符合函数定义,会引发未定义行为。
修复:去掉多余参数

struct SEED* oldArrayOfStructs = GetArrayOfStructs();

5. 输入缓冲区残留换行导致异常

UserInput中用getchar()读取选择后,缓冲区残留的换行符会被AddNew中第一个fgets读取,导致用户输入被跳过。
修复:清理输入缓冲区,同时简化AddNew中的fgets调用

void UserInput() {
  char choice;
  int choiceInt;

  printf("Add new item - print 1\n\n");
  printf("Input your choice: ");
  choice = getchar();
  // 清理缓冲区剩余字符
  while (getchar() != '\n');
  choiceInt = choice - '0';
  printf("\n");

  switch(choiceInt) {
    case 1:
      AddNew();
      break;
    default:
      printf("Bye!\n");
      break;
  }
}

AddNew中保留一次fgets即可:

printf("Input type, name, mass and price\nof the new seed with spaces: ");
fgets(tempChar, 200, stdin);

6. sscanf多余转义字符

AddNew中sscanf(tempChar, "%s %s %f %f\\n", ...)里的\\n是多余的,sscanf会自动跳过空白字符,反而可能导致匹配失败。
修复:去掉\\n

sscanf(tempChar, "%s %s %f %f", newType, newName, &newMass, &newPrice);

内容的提问来源于stack exchange,提问作者Maxymus 989

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 19:01:28