如何用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; }
关键步骤说明
- 整行读取处理:用
fgets读取每行完整内容,再通过strcspn移除换行符,避免后续分割时出现干扰。 - 动态分割单词:用
strtok函数按空格分割每行内容,第一个分割结果是水果名,后续所有结果都是喜欢该水果的人名。 - 映射关系存储:通过结构体数组维护人名与水果列表的映射,每次处理人名时,先检查是否已存在,存在则追加水果,不存在则新增条目。
- 结果输出:遍历结构体数组,按
人名: 水果1 水果2 ...的格式打印最终结果。
注意事项
- 代码中定义的
MAX_PEOPLE、MAX_FRUITS_PER_PERSON等宏是上限值,可根据实际数据规模调整,避免数组溢出。 - 若输入文件存在空行,代码会自动跳过,不影响最终结果。
- 文件打开失败时,
perror会输出具体错误原因,便于调试排查。
内容的提问来源于stack exchange,提问作者user14877200
相关产品推荐
相关产品推荐

