如何用C语言实现大小写可选的子串查找并显示其索引?
问题分析
你的代码现在只能匹配模式串的第一个字符,核心问题有这几点:
- 误用了
strchr()函数:它的作用是查找单个字符的首次出现,不是完整子串匹配 - 循环内的
break语句直接跳出循环,只处理了模式串的第一个字符 - 不区分大小写的逻辑只转换了模式串的小写,未同步处理原文本,匹配逻辑不完整
fgets()会把输入末尾的换行符\n读入字符串,这会干扰子串匹配(比如输入模式串后按回车,模式串里会多一个换行符,导致匹配失败)
修正方案
下面是修复后的代码,实现了完整的子串匹配,同时支持区分/不区分大小写:
#include <stdio.h> #include <ctype.h> #include <string.h> #define MAX_LENGTH 255 // 移除字符串末尾的换行符 void remove_newline(char *str) { str[strcspn(str, "\n")] = '\0'; } // 将字符串转为小写 void str_to_lower(char *str) { for (int i = 0; str[i]; i++) { str[i] = tolower((unsigned char)str[i]); } } int main(void) { char text[MAX_LENGTH], pattern[MAX_LENGTH], caseSelect; printf("Text:\n"); fgets(text, MAX_LENGTH, stdin); remove_newline(text); // 清理换行符 printf("Length of string: %zu\n", strlen(text)); printf("Match to:\n"); fgets(pattern, MAX_LENGTH, stdin); remove_newline(pattern); // 清理换行符 // 清理fgets残留的换行符,避免被scanf误读 while ((getchar()) != '\n'); printf("Should match be case-sensitive? (Y/N)\n"); scanf("%c", &caseSelect); caseSelect = toupper(caseSelect); char *match_pos = NULL; if (caseSelect == 'N') { // 文本和模式串统一转小写后匹配 char lower_text[MAX_LENGTH], lower_pattern[MAX_LENGTH]; strcpy(lower_text, text); strcpy(lower_pattern, pattern); str_to_lower(lower_text); str_to_lower(lower_pattern); match_pos = strstr(lower_text, lower_pattern); } else if (caseSelect == 'Y') { // 区分大小写,直接用strstr查找子串 match_pos = strstr(text, pattern); } else { printf("Invalid input.\n"); return 1; } if (match_pos != NULL) { // 通过指针差值计算匹配起始位置 int position = match_pos - text; printf("Matches at position %d.\n", position); } else { printf("No matches found.\n"); } return 0; }
关键修改说明
- 新增
remove_newline函数:解决fgets读取换行符导致的匹配干扰问题 - 新增
str_to_lower函数:统一转换字符串大小写,实现不区分大小写的匹配逻辑 - 用
strstr()替代strchr():strstr()是C标准库专门用于查找子串首次出现的函数 - 清理输入缓冲区:解决
fgets后scanf读取残留换行符的bug - 移除了原代码中多余的
break语句,确保完整执行子串匹配逻辑
如果需要找出所有匹配的位置(而非仅第一个),可以在找到第一个匹配后,从下一个字符开始循环调用strstr,直到返回NULL为止。
内容的提问来源于stack exchange,提问作者doingMyBest
相关产品推荐
相关产品推荐

