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
相关产品推荐
相关产品推荐

