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

C语言解析TXT构建规划系统时出现字符串重复错误求助

字符串解析重复错误的排查与解决

问题概述

在构建基于TXT文件的规划系统时,将文本内容转换为Event结构体的过程中出现字符串解析错误,随着程序运行错误愈发频繁,例如将"hungry"解析为"hungrygry",输出中出现大量拼接的垃圾字符。

错误原因分析

  1. C字符串缺少终止符:parseLine函数使用memcpy复制子串后,未手动添加字符串终止符'\0'。C语言中字符串必须以'\0'结尾,否则printf会持续读取内存直到遇到终止符,导致输出多余的垃圾数据。
  2. 未处理行尾无逗号的元素:原代码仅在遇到逗号时提取子串,若行尾元素后无直接逗号(直接到换行符),会漏掉该元素(当前输入文件虽有逗号,但需兼容通用情况)。
  3. 变量未初始化:main函数中Z和x未初始化,导致后续逻辑和输出出现错误值。
  4. 字符串比较逻辑错误:直接用==比较字符串是无效的,必须使用strcmp函数。
  5. 事件索引未递增:读取事件时未增加NbE,导致所有事件都会覆盖第一个Event元素。

修复方案

  1. 在parseLine函数中,每次memcpy复制子串后立即添加'\0'终止符。
  2. 循环结束后,检查是否存在未处理的行尾元素,若有则提取并添加终止符。
  3. 初始化main函数中的Z和x变量。
  4. 替换字符串比较方式为strcmp。
  5. 读取事件时递增NbE索引。

修复后的完整代码

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

typedef int bool;
#define TRUE 1
#define FALSE 0

// definir string
typedef char string[1024];

//Define event
typedef struct{
  string action[49],preconds[24],add[24],delete[24];
  int NbPreconds,NbAdd,NbDelete;
}Event;

int parseLine(char source[], string cible[]){
  int i=0, n=0; // i: source[], n: cible[]
  while(source[i]!=':') i++; // go until ':'
    i++; // avancer au debut de la premiere chaine
    int j=i;  // point beginning of first chain with j
  while(source[i]!='\n' && source[i] != '\0'){ // 兼容文件末尾无换行的情况
    if(source[i]==','){
      memcpy(&cible[n], &source[j], i-j); // extract characters from j to i
      cible[n][i-j] = '\0'; // 添加字符串终止符
      n++;
      j=i+1;   // j beginning of chain
    }
    i++;
  }
  // 处理行尾没有逗号的最后一个元素
  if(j < i){
    memcpy(&cible[n], &source[j], i-j);
    cible[n][i-j] = '\0';
    n++;
  }
  return n;
}

int main(){
  Event event[49];
  string start[49],finish[49];
  int NbStart,NbFinish,i,k,x=0,Z=0; // 初始化x和Z
  char source[100];
  FILE* txtfile = fopen("school.txt","r"); // insérer "monkeys.txt" / "blocs.txt" / "school.txt" pour choisir le fichier
  if(txtfile == NULL){ // tester le fichier s'il existe
    printf("Fichier inexistant.\n");
    exit(0);
  }
  else{
    printf("Fichier ouvert.\n");
  }
  //Lire les Conditions de départ & de Fin
  fgets(source,100,txtfile);
  NbStart=parseLine(source,start);
  printf("Condition Départ:\n");
  for(i=0; i<NbStart;i++){
    printf("  - %s\n",start[i]);
  }
  fgets(source,100,txtfile);
  string tempo[]={""};
  NbFinish=parseLine(source,finish);
  printf("Condition Fin:\n");
  for(i=0;i<NbFinish;i++){
    printf("  - %s\n",finish[i]);
  }
  //read action
  int NbE=0;
  while(fgets(source,100,txtfile)!=NULL){
    fgets(source,100,txtfile); // 跳过****分隔行
    if(feof(txtfile)) break; // 防止文件末尾多读导致错误
    parseLine(source, event[NbE].action);

    //read preconds
    fgets(source,100,txtfile);
    event[NbE].NbPreconds=parseLine(source, event[NbE].preconds);
    for(i=0;i<event[NbE].NbPreconds;i++){
      printf("Precond: %s\n",event[NbE].preconds[i]);
    }

    //read add
    fgets(source,100,txtfile);
    event[NbE].NbAdd=parseLine(source, event[NbE].add);
    for(i=0;i<event[NbE].NbAdd;i++){
      printf("Add: %s\n",event[NbE].add[i]);
    }
    //read delete
    fgets(source,100,txtfile);
    event[NbE].NbDelete=parseLine(source, event[NbE].delete);
    for(i=0;i<event[NbE].NbDelete;i++){
      printf("Delete: %s\n",event[NbE].delete[i]);
    }
    NbE++; // 递增事件索引,避免覆盖
  }
  bool Test=0; //Not complete
  while(Test==0){
    Test=1;
    Z=0; // 每次循环重置Z
    for(i=0;i<NbFinish;i++){ // 修正逻辑:检查finish的每个元素是否在start中
      int found = 0;
      for(k=0;k<NbStart;k++){
        if(strcmp(start[k], finish[i]) == 0){ // 使用strcmp比较字符串
          found = 1;
          break;
        }
      }
      if(!found){
        Test=0;
        break;
      }
    }
    x++; // 递增步骤数
    // 这里需要补充规划逻辑,当前逻辑只是示例,需根据实际需求完善
  }
  if(Test==1){
    printf("Le résultat a était trouvé en %d étapes.\n",x);
  }
  fclose(txtfile);
}

修复后验证结果

修复后,输出的预处理条件、添加项、删除项均为正确的字符串,无垃圾字符拼接,示例输出片段:

Fichier ouvert.  
Condition Départ:
  - at door      
  - on floor
  - has ball
  - hungry
  - chair at door
Condition Fin:
  - not hungry
Precond: chair at middle room
Precond: at middle room
Precond: on floor
Add: at bananas
Add: on chair
Delete: at middle room
Delete: on floor

Precond: chair at door
Precond: at door
Add: chair at middle room
Add: at middle room
Delete: chair at door
Delete: at door
...

内容的提问来源于stack exchange,提问作者Silver Winter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:57:54