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

不使用strcat时,如何通过分块strncmp并组合结果模拟strcmp的行为?

不使用strcat时,如何通过分块strncmp并组合结果模拟strcmp的行为?

哈哈,这个问题确实戳中了strcmp规则的“模糊地带”!我之前做字符串匹配优化的时候也碰到过类似需求——不想用strcat拼接(怕额外内存分配或者性能损耗),但又要精准模拟完整strcmp的行为,核心难点就是不能依赖strcmp的具体返回值,只能看它是负、零还是正,还要处理各种长度边界的情况。

先给你理清楚核心逻辑,再直接上可运行的代码:

首先,我们得明确strcmp的底层规则,这是所有逻辑的基础:

  1. 从第一个字符开始逐位比较,直到找到第一个不同的字符,返回该字符的差值(但标准只要求返回负、零、正,具体数值不做保证)
  2. 如果前面所有字符都相同,短的字符串更小,返回负(如果自身更短)或正(如果自身更长),完全相同则返回零

基于这个规则,我们可以把分块比较的逻辑拆成三步:

第一步:比较前缀和目标字符串的对应前缀部分

先拿前缀和目标字符串的开头比,长度取前缀的总长度。这一步的结果如果不是零,直接就能决定最终结果——因为前面的字符已经分出大小了,后面的后缀不影响。

第二步:前缀匹配时,处理长度边界

如果前缀和目标字符串的对应部分完全匹配,就要看目标字符串的长度和前缀长度的关系:

  • 要是目标字符串比前缀短:那我们的完整字符串(前缀+后缀)更长,直接返回正(符合“前面都相同,短的更小”的规则)
  • 要是目标字符串和前缀一样长:接下来直接比较后缀和目标字符串的剩余部分(也就是空字符串),这和strcmp的逻辑完全一致
  • 要是目标字符串比前缀长:就需要拿后缀和目标字符串的剩余部分继续比较

第三步:后缀比较的收尾逻辑

当后缀和目标字符串的剩余部分比较时,如果这部分有差异,直接返回对应符号;如果也完全匹配,就看谁还有剩余字符——目标字符串还有剩余就返回负,我们的字符串还有剩余就返回正,都没剩余就返回零。

完整代码实现

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

// 统一返回-1/0/1,避免依赖strcmp的具体返回值
static int get_sign(int val) {
    return (val > 0) - (val < 0);
}

int combined_strcmp(const char *prefix, const char *suffix, const char *pattern) {
    size_t prefix_len = strlen(prefix);
    size_t suffix_len = strlen(suffix);
    size_t pattern_len = strlen(pattern);
    size_t total_self_len = prefix_len + suffix_len;

    // 第一步:比较前缀和pattern的前prefix_len个字符
    int ret1 = strncmp(prefix, pattern, prefix_len);
    if (ret1 != 0) {
        // 前缀已经分出胜负,直接返回统一后的符号
        return get_sign(ret1);
    }

    // 前缀完全匹配,处理长度边界
    if (pattern_len < prefix_len) {
        // pattern比前缀短,自身字符串更长,返回正
        return 1;
    } else if (pattern_len == prefix_len) {
        // pattern和前缀等长,比较后缀和pattern的剩余部分(空字符串)
        return get_sign(strcmp(suffix, pattern + prefix_len));
    } else {
        // pattern比前缀长,比较后缀和pattern的剩余部分
        size_t remaining_pattern_len = pattern_len - prefix_len;
        int ret2 = strncmp(suffix, pattern + prefix_len, suffix_len);
        
        if (ret2 != 0) {
            return get_sign(ret2);
        }

        // 后缀也匹配,看谁还有剩余字符
        if (remaining_pattern_len > suffix_len) {
            // pattern还有剩余,自身更短,返回负
            return -1;
        } else if (remaining_pattern_len == suffix_len) {
            // 完全匹配
            return 0;
        } else {
            // 自身还有剩余,返回正
            return 1;
        }
    }
}

// 测试用例
int main() {
    const char *prefix = "super";
    const char *suffix = "man";
    // 测试1:和batman比较,应该返回正
    printf("Test 1: %d\n", combined_strcmp(prefix, suffix, "batman"));
    // 测试2:和super比较,应该返回正
    printf("Test 2: %d\n", combined_strcmp(prefix, suffix, "super"));
    // 测试3:和superman比较,应该返回0
    printf("Test 3: %d\n", combined_strcmp(prefix, suffix, "superman"));
    // 测试4:和supermen比较,应该返回负
    printf("Test 4: %d\n", combined_strcmp(prefix, suffix, "supermen"));
    // 测试5:和superma比较,应该返回正
    printf("Test 5: %d\n", combined_strcmp(prefix, suffix, "superma"));
    return 0;
}

关键细节说明

  1. get_sign函数:专门用来把strcmp/strncmp的返回值统一成-1、0、1,彻底避免依赖具体返回数值的风险,完全符合C标准的要求
  2. 长度用size_t:避免出现负数长度的问题,更符合C语言的类型规范
  3. 边界情况全覆盖:比如目标字符串比前缀短、比后缀长、刚好和完整字符串等长的情况都处理到了,完全对齐strcmp的逻辑

你可以把这个代码直接编译运行,测试用例覆盖了常见的场景,结果和直接调用strcmp("superman", pattern)完全一致。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:54:36