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

C语言不使用tolower实现CamelCase转snake_case问题求助

问题根因分析
  • 长度不匹配:小驼峰转下划线命名时,每出现一个大写字母,最终字符串长度会比原串多1(需要插入1个下划线)。你当前的代码直接将string[i-1]赋值为下划线,直接覆盖了原位置的正常字符,比如示例中helloWorld里W的下标为5,赋值string[4] = '_'就把原本的o覆盖了,自然得到错误结果hell_world。
  • 无字符移位逻辑:插入下划线需要把大写字母及之后的所有字符向后移动1位,腾出位置放下划线,你当前代码没有这步操作。
正确实现方案

这里提供两种常用的实现方式:

方案1:原地修改(要求传入的缓冲区足够容纳转换后的字符串)

#include <string.h>

void snake_case(char *string) {
    int len = strlen(string);
    int upper_count = 0;
    // 先统计大写字母数量,确定最终需要的长度
    for (int i = 0; i < len; i++) {
        if (string[i] >= 'A' && string[i] <= 'Z') {
            upper_count++;
        }
    }
    // 从后往前遍历移位,避免覆盖未处理的字符
    int old_pos = len;
    int new_pos = len + upper_count;
    // 字符串末尾的'\0'也要一起移动
    while (old_pos >= 0) {
        if (string[old_pos] >= 'A' && string[old_pos] <= 'Z') {
            // 大写转小写
            string[new_pos] = string[old_pos] + 32;
            // 往前挪一位放下划线
            new_pos--;
            string[new_pos] = '_';
        } else {
            // 普通字符直接移动
            string[new_pos] = string[old_pos];
        }
        old_pos--;
        new_pos--;
    }
}

注意:调用该函数时,传入的string对应的缓冲区大小至少要为原字符串长度 + 大写字母数量 + 1,否则会出现缓冲区溢出。

方案2:返回新分配的字符串(更安全,不需要调用方提前准备大缓冲区)

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

char* snake_case(const char *input) {
    int len = strlen(input);
    int upper_count = 0;
    for (int i = 0; i < len; i++) {
        if (input[i] >= 'A' && input[i] <= 'Z') {
            upper_count++;
        }
    }
    // 分配内存:原长度 + 下划线数量 + 末尾'\0'的1位
    char *result = (char*)malloc(len + upper_count + 1);
    if (!result) return NULL;
    int res_pos = 0;
    for (int i = 0; i < len; i++) {
        if (input[i] >= 'A' && input[i] <= 'Z') {
            result[res_pos] = '_';
            res_pos++;
            result[res_pos] = input[i] + 32;
        } else {
            result[res_pos] = input[i];
        }
        res_pos++;
    }
    result[res_pos] = '\0';
    return result;
}

注意:调用方使用完返回的字符串后需要手动调用free()释放内存,避免内存泄漏。

补充说明:如果输入可能是首字母大写的大驼峰格式(如HelloWorld),不需要开头的下划线的话,可以在方案2的循环结束后增加判断:如果result[0] == '_',就将result整体后移一位,或者统计大写字母时排除首字母的大写即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:00:04