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

C语言大小写敏感/不敏感子串删除代码异常排查求助

C语言删除指定子串代码的问题排查

我写了一段C语言代码,用于删除字符串中的指定子串,通过case_sensitive参数控制是否区分大小写(0表示不区分,1表示区分),但运行结果不符合预期。

预期效果

  • 输入字符串"abcdef cde AbCDE"、子串"abc":
    • 当case_sensitive=1时,应返回"def cde AbCDE"
    • 当case_sensitive=0时,应返回"def cde DE"
  • 输入字符串"xYXyXYXY"、子串"xy"且case_sensitive=0时,应返回空串

原代码

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

int erase_once(char *input_string, const char *substring, int case_sensitive) {
    size_t string_length = strlen(input_string);
    size_t substring_length = strlen(substring);

    if (string_length < substring_length || substring_length == 0) return 0;

    size_t i;
    for (i = 0; i < string_length - substring_length + 1; i++) {
        int match_found = 1;

        for (size_t j = i; j < i + substring_length; j++) {
            if ((case_sensitive == 0 &&
                 tolower(input_string[j]) != tolower(substring[j-i])) ||
                input_string[j] != substring[j-i]) {
                match_found = 0;
                break;
            }
        }

        if (!match_found) continue;

        for (; i < string_length - substring_length; i++) {
            input_string[i] = input_string[i + substring_length];
        }
        input_string[i] = '\0';

        return 1;
    }

    return 0;
}

int erase(char *input_string, const char *substring, int case_sensitive) {
    int count;
    for (count = 0; erase_once(input_string, substring, case_sensitive); count++);
    return count;
}

int main(void) {
    char main_string[] = "abcdef cde AbCDE";
    const char *substring_to_erase = "abc";

    erase(main_string, substring_to_erase, 0);
    printf("%s\n", main_string);

    return 0;
}

错误分析与修正

1. 匹配逻辑核心错误

原代码中字符匹配的条件逻辑完全颠倒:

if ((case_sensitive == 0 && tolower(input_string[j]) != tolower(substring[j-i])) ||
    input_string[j] != substring[j-i])

这个条件会导致不管是否区分大小写,只要原字符与子串字符不相等,就判定不匹配。即使不区分大小写时转小写匹配成功,只要原字符不一致,仍会标记为不匹配,完全违背需求。

正确逻辑应该是分支判断:

  • 区分大小写:直接比较原字符
  • 不区分大小写:转小写后比较

修正后的匹配代码:

for (size_t j = 0; j < substring_length; j++) { // j从0开始对应子串索引,更清晰
    char c1 = input_string[i + j];
    char c2 = substring[j];
    if (case_sensitive) {
        if (c1 != c2) {
            match_found = 0;
            break;
        }
    } else {
        // 转unsigned char避免tolower处理负数字符(如扩展ASCII)
        if (tolower((unsigned char)c1) != tolower((unsigned char)c2)) {
            match_found = 0;
            break;
        }
    }
}

2. 删除子串的代码优化(次要)

原代码用手动循环移动字符,可替换为memmove,代码更简洁且不易出错:

memmove(input_string + i, input_string + i + substring_length, 
        string_length - i - substring_length + 1);

修正后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

int erase_once(char *input_string, const char *substring, int case_sensitive) {
    size_t string_length = strlen(input_string);
    size_t substring_length = strlen(substring);

    if (string_length < substring_length || substring_length == 0) return 0;

    for (size_t i = 0; i <= string_length - substring_length; i++) {
        int match_found = 1;
        for (size_t j = 0; j < substring_length; j++) {
            char c1 = input_string[i + j];
            char c2 = substring[j];
            if (case_sensitive) {
                if (c1 != c2) {
                    match_found = 0;
                    break;
                }
            } else {
                if (tolower((unsigned char)c1) != tolower((unsigned char)c2)) {
                    match_found = 0;
                    break;
                }
            }
        }

        if (!match_found) continue;

        memmove(input_string + i, input_string + i + substring_length, 
                string_length - i - substring_length + 1);
        return 1;
    }

    return 0;
}

int erase(char *input_string, const char *substring, int case_sensitive) {
    int count = 0;
    while (erase_once(input_string, substring, case_sensitive)) {
        count++;
    }
    return count;
}

int main(void) {
    // 测试用例1:不区分大小写删除"abc"
    char main_string1[] = "abcdef cde AbCDE";
    const char *sub1 = "abc";
    erase(main_string1, sub1, 0);
    printf("测试1结果:%s\n", main_string1); // 输出"def cde DE"

    // 测试用例2:区分大小写删除"abc"
    char main_string2[] = "abcdef cde AbCDE";
    erase(main_string2, sub1, 1);
    printf("测试2结果:%s\n", main_string2); // 输出"def cde AbCDE"

    // 测试用例3:不区分大小写删除"xy",结果为空串
    char main_string3[] = "xYXyXYXY";
    const char *sub2 = "xy";
    erase(main_string3, sub2, 0);
    printf("测试3结果:'%s'\n", main_string3); // 输出空串

    return 0;
}

验证结果

运行修正后的代码,三个测试用例均符合预期效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 03:01:09