C语言子串移除函数仅生效一次的问题排查求助
问题排查与说明
你的izbaci_tekst函数逻辑本身是可以多次移除目标子串的,你遇到的测试案例问题并非函数bug,而是测试输入与期望不匹配:
测试案例的矛盾点
输入字符串"aaaabcbcbcbc"的字符序列是a,a,a,a,b,c,b,c,b,c,b,c,其中仅存在一个"abc"子串(从第4个a开始,索引3-5)。移除该子串后,剩余字符串为"aaabcbcbc",这是完全正确的结果,而你标注的期望输出空字符串是不符合实际的——原输入里根本没有足够多的"abc"子串可以移除到空。
验证函数的多次移除能力
如果用包含多个目标子串的输入测试,比如:
char niz[] = "abcabcabc"; printf("'%s'", izbaci_tekst(niz, "abc", 1));
函数会正确输出'',说明它能循环匹配并移除所有符合条件的子串。
函数逻辑的正确性说明
函数核心逻辑是:
- 遍历字符串,逐个位置检查是否匹配目标子串(区分/不区分大小写由
cs控制) - 找到匹配后,将后续字符前移覆盖目标子串,更新字符串长度
- 将索引
i--,确保移除后新暴露的字符位置能被重新检查(比如"ababc"移除第一个"ab"后,新字符串"abc"的起始位置需要被再次检查)
这个逻辑是完整的,没有问题。
额外优化建议(非必须)
可以用指针操作替代数组索引,让代码更简洁高效,比如:
char* izbaci_tekst(char* str, const char* tekst, int cs){ char* ptr = str; int tekst_len = strlen(tekst); if (tekst_len == 0) return str; while (*ptr) { char* match = ptr; const char* t_ptr = tekst; int matched = 1; while (*t_ptr) { char sc = cs ? *match : tolower(*match); char tc = cs ? *t_ptr : tolower(*t_ptr); if (sc != tc) { matched = 0; break; } match++; t_ptr++; } if (matched) { memmove(ptr, match, strlen(match) + 1); } else { ptr++; } } return str; }
内容的提问来源于stack exchange,提问作者Irma Ibrović
相关产品推荐
相关产品推荐

