如何在C程序中实现对TXT文件中含空格字符串的精确匹配搜索?
解决C语言TXT文件中带空格字符串的精确匹配问题
我先帮你梳理下原代码里的核心问题,再给出能实现带空格字符串精确匹配的解决方案:
原代码的问题分析
- 变量逻辑混乱:你把传入的搜索目标
title当成了存储文件行的缓冲区,fgets(title, sizeof(title), ptr_to_library)这行不仅会覆盖用户要搜索的关键词,而且因为函数参数中的数组会退化为指针,sizeof(title)得到的是指针大小(通常4/8字节),根本读不全带空格的长行内容,导致匹配失败。 - 匹配逻辑错误:
strstr(string, title)是判断目标是否为文件行的子串,这就是输入"he"会匹配"hello"的原因——它做的是部分匹配,而非精确匹配。 - 未处理换行符:
fgets会读取文件每行末尾的\n,就算内容完全一致,带换行符的行和用户输入的无换行目标也会匹配失败。 - 资源泄漏:原代码没有关闭打开的文件,会导致系统资源占用。
修正后的精确匹配代码
#include <stdio.h> #include <string.h> struct Book { char *title; char *authors; unsigned int year; unsigned int copies; }; int existance_of_book(const char *target_title) { // 定义足够大的缓冲区存储文件每行内容,适配带空格的书名 char line_buffer[256]; FILE *ptr_to_library = fopen("library.txt", "r"); // 用局部文件指针替代全局变量,避免冲突 if(ptr_to_library == NULL) { printf("\nERROR: cannot open file\n"); return -1; } while (fgets(line_buffer, sizeof(line_buffer), ptr_to_library) != NULL) { // 移除行尾的换行符(如果存在) size_t line_len = strlen(line_buffer); if (line_len > 0 && line_buffer[line_len - 1] == '\n') { line_buffer[line_len - 1] = '\0'; } // 用strcmp做完全相等的精确匹配 if (strcmp(line_buffer, target_title) == 0) { printf("book found\n"); fclose(ptr_to_library); // 找到后立即关闭文件 return 1; } } fclose(ptr_to_library); // 遍历结束后关闭文件 return 0; }
关键优化点说明
- 独立缓冲区存储文件行:用
line_buffer专门存储读取的文件内容,避免覆盖搜索目标,且设置足够大的容量容纳带空格的书名。 - 处理换行符:手动移除
fgets读入的换行符,确保和用户输入的目标字符串格式一致。 - 精确匹配逻辑:用
strcmp替代strstr,只有当两个字符串完全逐字符相等时才返回匹配结果,彻底解决部分匹配误判问题。 - 局部文件指针:避免使用全局变量,减少多场景调用时的资源冲突风险,同时确保文件始终被正确关闭。
扩展:如果文件存储整本书信息的情况
如果你的library.txt每行存储的是struct Book对应的完整信息(比如格式为书名|作者|年份|库存),可以通过拆分字符串提取书名后再匹配:
// 假设每行格式:"书名|作者|年份|库存" while (fgets(line_buffer, sizeof(line_buffer), ptr_to_library) != NULL) { char book_title[256], book_authors[256]; unsigned int book_year, book_copies; // 按分隔符拆分每行内容 if (sscanf(line_buffer, "%[^|]|%[^|]|%u|%u", book_title, book_authors, &book_year, &book_copies) == 4) { // 移除书名末尾的换行符 size_t title_len = strlen(book_title); if (title_len > 0 && book_title[title_len - 1] == '\n') { book_title[title_len - 1] = '\0'; } if (strcmp(book_title, target_title) == 0) { printf("book found\n"); fclose(ptr_to_library); return 1; } } }
内容的提问来源于stack exchange,提问作者gretta
相关产品推荐
相关产品推荐

