C语言实现表格文本文件动物位置搜索的最优方法问询
动物位置搜索功能实现方案
问题背景
我有一个table.txt文件,内容如下:
class #1 Sect1: cat Sect2: dog Sect3: mouse Sect4: bird Sect5: squirrel class#2 Sect1: shark Sect2: octopus Sect3: tuna Sect4: eel Sect5: dolphin
需要实现功能:提示用户输入动物名称,搜索文件内容后输出该动物的位置(例如输入mouse,输出The animal mouse is located at Class #1 in Sect#3)。
现有C代码已完成文件读取到缓冲区的部分,但搜索逻辑尚未实现,同时不确定是将每行存入数组还是用结构体组织数据更优,也不清楚当前缓冲区是否适合直接搜索,需要先解析内容。
现有代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { FILE* infile; char* buffer; long numbytes; char animal[10]; char class[10]; char sect[10]; infile = fopen("table.txt", "r"); if (NULL == infile) { printf("file can't be opened \n"); return 1; // 原代码未处理此分支的退出逻辑,会导致后续错误 } /* 获取文件字节数 */ fseek(infile, 0L, SEEK_END); numbytes = ftell(infile); /* 重置文件指针到开头 */ fseek(infile, 0L, SEEK_SET); /* 分配缓冲区内存 */ buffer = (char*)calloc(numbytes, sizeof(char)); /* 内存分配失败处理 */ if (buffer == NULL) return 1; /* 将文件内容读入缓冲区 */ fread(buffer, sizeof(char), numbytes, infile); fclose(infile); // 原代码此处已关闭文件,后续重复关闭会报错 printf("Enter animal to search: "); scanf("%s", animal); // 待实现搜索逻辑 printf("\nThe aninmal %s is located in %s and %s", animal, class, sect); /* 释放缓冲区内存 */ free(buffer); // 重复关闭文件,存在错误 fclose(infile); return 0; }
解决方案
思路分析
直接在缓冲区搜索虽然可行,但代码维护性差、扩展性弱。更优的方式是先将缓冲区内容解析为结构化数据(比如结构体数组),把每个动物的位置信息规整存储,后续搜索逻辑会更清晰高效。
修改后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 定义结构体存储动物的位置信息 typedef struct { char animal_name[20]; char class[10]; char section[10]; } AnimalLocation; int main() { FILE* infile; char* buffer; long numbytes; char animal[20]; AnimalLocation* locations = NULL; int location_count = 0; char* line_start; char* line_end; char current_class[10] = {0}; infile = fopen("table.txt", "r"); if (NULL == infile) { printf("file can't be opened \n"); return 1; } // 获取文件大小并分配缓冲区(多1字节存字符串结束符) fseek(infile, 0L, SEEK_END); numbytes = ftell(infile); fseek(infile, 0L, SEEK_SET); buffer = (char*)calloc(numbytes + 1, sizeof(char)); if (buffer == NULL) { fclose(infile); return 1; } fread(buffer, sizeof(char), numbytes, infile); fclose(infile); // 逐行解析缓冲区内容 line_start = buffer; while (line_start < buffer + numbytes) { // 定位行尾(换行符或文件末尾) line_end = strchr(line_start, '\n'); if (!line_end) { line_end = buffer + numbytes; } *line_end = '\0'; // 将换行符替换为结束符,方便单行处理 // 跳过空行 if (strlen(line_start) == 0) { line_start = line_end + 1; continue; } // 识别并记录当前class if (strstr(line_start, "class") != NULL) { strncpy(current_class, line_start, sizeof(current_class) - 1); current_class[sizeof(current_class)-1] = '\0'; // 统一class格式:将class#2转为class #2(可选,匹配示例输出格式) char* hash_pos = strchr(current_class, '#'); if (hash_pos && hash_pos > current_class + 5) { memmove(hash_pos + 1, hash_pos, strlen(hash_pos)); *hash_pos = ' '; } } // 解析Sect行,存储动物位置信息 else if (strstr(line_start, "Sect") != NULL) { char* colon_pos = strchr(line_start, ':'); if (colon_pos) { // 扩容结构体数组 locations = realloc(locations, sizeof(AnimalLocation) * (location_count + 1)); if (!locations) { free(buffer); return 1; } // 提取章节信息 strncpy(locations[location_count].section, line_start, colon_pos - line_start); locations[location_count].section[colon_pos - line_start] = '\0'; // 提取动物名称(跳过冒号后的空格) strncpy(locations[location_count].animal_name, colon_pos + 2, sizeof(locations[location_count].animal_name) - 1); locations[location_count].animal_name[sizeof(locations[location_count].animal_name)-1] = '\0'; // 记录当前所属class strcpy(locations[location_count].class, current_class); location_count++; } } line_start = line_end + 1; } // 接收用户输入 printf("Enter animal to search: "); scanf("%s", animal); // 搜索目标动物 int found = 0; for (int i = 0; i < location_count; i++) { if (strcmp(locations[i].animal_name, animal) == 0) { printf("\nThe animal %s is located at %s in %s", animal, locations[i].class, locations[i].section); found = 1; break; // 假设动物名称唯一,找到即退出 } } if (!found) { printf("\nAnimal %s not found", animal); } // 释放资源 free(buffer); if (locations) { free(locations); } return 0; }
代码说明
- 结构体设计:用
AnimalLocation统一存储每个动物的名称、所属类和章节,结构化数据便于后续搜索和维护。 - 缓冲区解析:逐行处理缓冲区内容,先识别当前class,再解析每个Sect行,将信息存入结构体数组。
- 搜索逻辑:遍历结构体数组,对比动物名称,找到后输出标准格式的位置信息;未找到则提示。
- 错误修复:解决了原代码中重复关闭文件、未初始化变量、缓冲区无结束符等问题。
内容的提问来源于stack exchange,提问作者KSH_07
相关产品推荐
相关产品推荐

