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

C语言递归实现字符串转全大写函数测试失败问题排查

C语言递归实现字符串转大写函数测试失败问题修复

问题背景

  • 开发需求:使用C语言编写递归函数,将包含任意字符的字符串转换为全大写形式,实现过程禁止使用toupper()及其他同类内置大小写转换函数
  • 初始实现代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* allCapStringRec(char str[])
{
    if (str[0] == '\0' )
        return 0; 

    if (str[0] >= 'a' && str[0] <= 'z')
        str[0] = str[0] - 32;

    return allCapStringRec(str+1);
}
  • 测试代码:
void Test3(char str[], char expected[], int dec)
{
    char *result = allCapStringRec(str);

    if (strcmp(result, expected) != 0)
        printf("allCapStringRec => Your Output is %s, Expected: %s\n", result, expected);
}

int main()
{
    Test3("123321", "123321", 4);
    Test3("abBba", "ABBBA", 4);
    Test3("ab$cd", "AB$CD", 4);

    printf("done");
    return 0;
}
  • 实际运行报错:
allCapStringRec => Your Output is , Expected: 123321

错误原因定位

代码存在1个核心逻辑错误,另有1个潜在隐患:

  1. 递归返回值逻辑完全错误
    每一层递归都直接返回下一层递归的调用结果,最终整个函数返回的是递归到最深处(字符串末尾\0位置)的返回值。终止条件中写的return 0;会返回空指针NULL,测试代码把空指针传入strcmp会直接读取异常;就算把终止条件改成返回当前指针,最终返回的也是指向字符串末尾结束符的指针,strcmp从结束符位置开始比较,得到的结果就是空字符串,和当前看到的输出完全一致。
  2. 潜在隐患:字符串字面量不可修改
    测试代码中直接传入了"123321"这类字符串字面量作为入参,字符串字面量存储在内存只读区域,直接修改会触发段错误,属于测试代码的编写问题,实际调用时应该先将字面量复制到可写的字符数组中再传入函数。

修复后代码

只需要调整递归的返回逻辑,递归处理后续字符串后,返回当前层的字符串起始地址即可,这样最外层调用最终会返回原字符串的首地址:

char* allCapStringRec(char str[])
{
    // 递归终止:到达字符串末尾,返回当前指针
    if (str[0] == '\0') {
        return str;
    }

    // 小写字母转大写(ASCII码中小写比对应大写大32)
    if (str[0] >= 'a' && str[0] <= 'z') {
        str[0] -= 32;
    }

    // 递归处理后续字符,不需要接收递归返回值
    allCapStringRec(str + 1);

    // 返回当前层的字符串起始地址,最外层会返回原字符串首地址
    return str;
}

修复后函数会原地修改传入的可写字符串,并且返回字符串首地址,完全符合测试代码的调用要求。

补充:如果要适配测试代码中直接传入字符串字面量的场景,需要在函数内部先申请足够的内存复制原字符串,再对复制后的字符串做递归转换,最后返回复制后字符串的首地址即可,注意使用后需要手动释放内存避免泄漏。

内容的提问来源于stack exchange,提问作者Peace and Love

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:01:04