You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

K&R C问题:大小写不敏感strstrci函数匹配末尾字符串返回NULL排查

问题分析与修复

核心错误

你写的strstrci函数在匹配位于字符串末尾(或中间但后续还有字符)的模式时会返回NULL,问题出在内层循环的逻辑顺序上:

你错误地把模式的结束符'\0'也纳入了字符匹配条件。按照strstr的定义,只要模式p的所有字符在s中连续匹配(大小写不敏感),就应该返回起始位置,不管s后续是否还有字符。但你的代码要求,当模式匹配到末尾时,s的对应位置也必须是'\0'才能触发返回——这就导致如果s在模式匹配完成后还有其他字符,或者测试字符串没有正确以'\0'结尾,函数就会返回NULL。

比如你提到的例子s="On a wall he sat"、p="sat",如果字符串正确以'\0'结尾,理论上你的代码应该能返回正确指针,但如果字符串末尾有隐藏字符(比如换行符),或者测试时字符串没有正确终止,就会触发错误。但函数本身的逻辑缺陷是根本问题。

修复后的代码

调整内层循环的判断顺序,先检查模式是否匹配完成,再处理字符匹配:

char * strstrci(char *s, char *p)
{
    int i, j;
    // 空模式直接返回原字符串,符合strstr标准行为
    if (*p == '\0')
        return s;
        
    for (i = 0; *(s + i) != '\0'; i++)
    {
        char s_char = *(s + i);
        char p_char = *p;
        // 判断首字符是否大小写匹配,仅对字母做转换判断
        if ((s_char == p_char) || 
            (p_char >= 'A' && p_char <= 'Z' && s_char == p_char + 32) || 
            (p_char >= 'a' && p_char <= 'z' && s_char == p_char - 32))
        {
            for (j = 1; ; j++)
            {
                // 模式遍历完,说明完全匹配
                if (*(p + j) == '\0')
                    return s + i;
                // 字符串遍历完但模式没结束,匹配失败
                if (*(s + i + j) == '\0')
                    break;
                    
                s_char = *(s + i + j);
                p_char = *(p + j);
                // 当前字符不匹配,退出内层循环
                if (!((s_char == p_char) || 
                      (p_char >= 'A' && p_char <= 'Z' && s_char == p_char + 32) || 
                      (p_char >= 'a' && p_char <= 'z' && s_char == p_char - 32)))
                {
                    break;
                }
            }
        }
    }
    return NULL;
}

额外优化点

  1. 增加了空模式处理,和标准strstr行为一致。
  2. 加入字母范围判断,避免对数字、符号等非字母字符做无效的大小写转换。
  3. 内层循环逻辑更清晰:先确认模式是否匹配完成,再检查字符串是否结束,最后判断字符匹配,完全符合字符串匹配的逻辑顺序。

内容的提问来源于stack exchange,提问作者Vinayak Deshmukh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:52:31