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

如何用C语言的fgets读取txt文件换行,实现按人物归类水果列表?

解决方法:从不规则行文本中整理水果与人名的映射

针对你遇到的每行单词数不固定的问题,核心思路是先读取整行内容,再分割单词处理,具体实现如下:

完整代码实现

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

#define MAX_NAME_LEN 20
#define MAX_FRUIT_LEN 20
#define MAX_PEOPLE 10  // 根据实际人数调整上限
#define MAX_FRUITS_PER_PERSON 10  // 根据每人对应水果数调整上限

// 存储单个人的名字及对应水果列表
typedef struct {
    char name[MAX_NAME_LEN];
    char fruits[MAX_FRUITS_PER_PERSON][MAX_FRUIT_LEN];
    int fruit_count;
} Person;

Person people[MAX_PEOPLE];
int people_count = 0;

// 查找指定人名是否已存在,返回索引;不存在返回-1
int find_person(const char *name) {
    for (int i = 0; i < people_count; i++) {
        if (strcmp(people[i].name, name) == 0) {
            return i;
        }
    }
    return -1;
}

// 将水果添加到对应人名的列表中
void add_fruit_to_person(const char *name, const char *fruit) {
    int idx = find_person(name);
    if (idx == -1) {
        // 新增人物
        if (people_count >= MAX_PEOPLE) {
            fprintf(stderr, "人数超出设定上限,请修改MAX_PEOPLE的值\n");
            exit(EXIT_FAILURE);
        }
        strcpy(people[people_count].name, name);
        strcpy(people[people_count].fruits[0], fruit);
        people[people_count].fruit_count = 1;
        people_count++;
    } else {
        // 给已有人物追加水果
        if (people[idx].fruit_count >= MAX_FRUITS_PER_PERSON) {
            fprintf(stderr, "%s的水果数量超出设定上限,请修改MAX_FRUITS_PER_PERSON的值\n", name);
            exit(EXIT_FAILURE);
        }
        strcpy(people[idx].fruits[people[idx].fruit_count], fruit);
        people[idx].fruit_count++;
    }
}

int main() {
    FILE *fp = fopen("fruits.txt", "r");
    if (!fp) {
        perror("打开文件失败");
        return EXIT_FAILURE;
    }

    char line[100];  // 假设每行字符数不超过100,可按需调整
    while (fgets(line, sizeof(line), fp) != NULL) {
        // 移除换行符(fgets会读取换行符到line中)
        line[strcspn(line, "\n")] = '\0';
        
        // 分割第一个单词(水果名)
        char *token = strtok(line, " ");
        if (!token) continue;  // 跳过空行
        char fruit[MAX_FRUIT_LEN];
        strcpy(fruit, token);

        // 分割后续所有单词(人名)
        while ((token = strtok(NULL, " ")) != NULL) {
            add_fruit_to_person(token, fruit);
        }
    }

    fclose(fp);

    // 按要求格式输出结果
    for (int i = 0; i < people_count; i++) {
        printf("%s: ", people[i].name);
        for (int j = 0; j < people[i].fruit_count; j++) {
            if (j > 0) printf(" ");
            printf("%s", people[i].fruits[j]);
        }
        printf("\n");
    }

    return EXIT_SUCCESS;
}

关键步骤说明

  1. 整行读取处理:用fgets读取每行完整内容,再通过strcspn移除换行符,避免后续分割时出现干扰。
  2. 动态分割单词:用strtok函数按空格分割每行内容,第一个分割结果是水果名,后续所有结果都是喜欢该水果的人名。
  3. 映射关系存储:通过结构体数组维护人名与水果列表的映射,每次处理人名时,先检查是否已存在,存在则追加水果,不存在则新增条目。
  4. 结果输出:遍历结构体数组,按人名: 水果1 水果2 ...的格式打印最终结果。

注意事项

  • 代码中定义的MAX_PEOPLE、MAX_FRUITS_PER_PERSON等宏是上限值,可根据实际数据规模调整,避免数组溢出。
  • 若输入文件存在空行,代码会自动跳过,不影响最终结果。
  • 文件打开失败时,perror会输出具体错误原因,便于调试排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:45:41