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

如何读取文本文件中可变数量前置任务ID及标题填充Task结构体

解决可变数量前置任务与任务标题的文件读取问题

你的问题核心是处理每行中可变数量的前置任务ID,同时还要捕获可能包含空格的任务标题——原代码只读取了前三个固定字段,自然没法处理后面的可变内容。我给你提供一个实用的解决方案,用字符串分割的方式来灵活处理这些字段:

核心思路

因为每行的字段是用空格分隔的,我们可以用strtok函数把整行拆成一个个"令牌"(token),然后按顺序处理:

  1. 先提取前三个固定字段:任务ID、时长、前置任务数量
  2. 根据前置任务数量,提取对应个数的前置ID存入数组
  3. 把剩下的所有令牌拼接起来,作为任务标题(毕竟标题可能包含空格,比如permis exploitation这种)

修改后的完整代码

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

// 根据你的需求调整这两个宏的大小
#define NMAXPREV 10
#define LGMAX 100

typedef struct{
    int id;
    int duration;
    int nbPrev; /* 所需前置任务的数量 */
    int prev[NMAXPREV]; /* 所需前置任务ID数组 */
    char title[LGMAX];
}Task ;

int readTasksFile(char* file_name, Task t[]) {
    FILE* f;
    char line[256] = {'\0'};
    int taskCount = 0;

    // 打开文件失败的错误处理
    if((f = fopen(file_name, "r")) == NULL) {
        perror("The file couldn't be opened");
        exit(EXIT_FAILURE);
    }

    // 逐行读取文件
    while (fgets(line, 256, f) != EOF) {
        // 去掉行尾的换行符,避免标题里带换行
        size_t lineLen = strlen(line);
        if (lineLen > 0 && line[lineLen-1] == '\n') {
            line[lineLen-1] = '\0';
        }

        Task* current = &t[taskCount];
        char* token = strtok(line, " ");
        int tokenIdx = 0;

        // 读取任务ID
        if (token) {
            current->id = atoi(token);
            tokenIdx++;
            token = strtok(NULL, " ");
        }

        // 读取任务时长
        if (token) {
            current->duration = atoi(token);
            tokenIdx++;
            token = strtok(NULL, " ");
        }

        // 读取前置任务数量
        if (token) {
            current->nbPrev = atoi(token);
            tokenIdx++;
            token = strtok(NULL, " ");
        }

        // 读取可变数量的前置任务ID
        int prevIdx = 0;
        while (prevIdx < current->nbPrev && token) {
            current->prev[prevIdx] = atoi(token);
            prevIdx++;
            token = strtok(NULL, " ");
        }

        // 拼接剩余所有token作为任务标题(处理带空格的标题)
        current->title[0] = '\0';
        while (token) {
            // 如果标题已有内容,先加空格分隔
            if (strlen(current->title) > 0) {
                strcat(current->title, " ");
            }
            // 安全拼接,避免缓冲区溢出
            strncat(current->title, token, LGMAX - strlen(current->title) - 1);
            token = strtok(NULL, " ");
        }

        taskCount++;
    }

    fclose(f);
    // 返回实际读取的任务数量,比返回0更有意义
    return taskCount;
}

关键细节说明

  • 处理换行符:fgets会把行尾的\n也读进来,我们提前去掉它,避免标题里出现不必要的换行符
  • 安全拼接标题:用strncat而不是直接strcat,防止标题过长导致缓冲区溢出
  • 返回任务数量:原代码返回0没什么用,改成返回实际读取的任务数,调用者可以直接知道有多少个任务被加载
  • 边界情况处理:比如前置任务数量为0的行(像第一行0 0 0 debut),代码会直接跳过前置ID的读取,直接处理标题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 14:48:12