如何编写程序判断字符串命名格式并解决单词首字母识别问题?
如何判断字符串属于Pascal/Camel/Snake/Kebab命名格式?
需求说明
需要编写程序判断输入字符串属于以下四种命名格式之一,或为未定义格式:
- Pascal case:首字母大写,后续单词首字母大写,无分隔符(例:
HelloWorld) - camel case:首字母小写,后续单词首字母大写,无分隔符(例:
helloWorld) - snake case:单词间用下划线
_分隔,所有字母小写(例:hello_world) - kebab case:单词间用连字符
-分隔,所有字母小写(例:hello-world)
输入规则
- 第一行输入整数
n,表示待判断的字符串数量 - 接下来
n行,每行输入整数k(字符串长度)和一个无空格字符串
输入示例
3 11 masterShifu 12 master_shifu 12 MASTER_SHIFU
输出示例
camel case
snake case
undefined case style
遇到的问题
由于单词之间无空格,无法准确识别单词首字母,现有代码逻辑存在错误,无法正确判断格式。
现有代码
#include <stdio.h> #include <ctype.h> int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i++) { int k; scanf("%d ", &k); char word[k]; gets(word[k]); int count = 0; if (isupper(word[0]) == 1) { for (int i = 1; i < n; i++) { if (isupper(word[i]) == 1) { count++; } } if (count == k) printf("Undefined Case Style\n"); else printf("PascalCase\n"); } else { int c = 0, s = 0, count = 0; for (int i = 0; i < n; i++) { if (word[i] == '-') { c++; printf("kebab-case\n"); break; } else if (word[i] == '_') // snake case { s++; printf("snake_case\n"); break; } else if (isupper(word[i]) == 1) // camel case { count++; printf("camelCase\n"); break; } } if (c == 0 && s == 0) printf("Undefined Case Style\n"); } } return 0; }
代码问题分析
- 输入读取错误:
gets(word[k])是错误用法,gets需传入数组首地址,且该函数不安全,建议用scanf("%s", word)替代 - 循环范围错误:多处循环误用
n(字符串总数)而非k(当前字符串长度),导致越界或判断不完整 isupper判断逻辑错误:isupper返回非零值表示大写,不是固定的1,应直接用if (isupper(word[i]))判断- 逻辑漏洞:
- 仅检测到第一个分隔符或大写字母就直接输出,未验证整个字符串是否完全符合格式(如同时含
_和-的字符串会被误判) - 未处理全大写加分隔符的情况(如输入
MASTER_SHIFU) - Pascal case判断逻辑错误,仅检查首字母大写和后续大写字母数量,未验证大写字母是否为合法单词开头(如全大写字符串会被误判)
- 仅检测到第一个分隔符或大写字母就直接输出,未验证整个字符串是否完全符合格式(如同时含
解决方案思路
按优先级依次验证格式:
- 先检查分隔符类型:
- 含
_:验证所有分隔符都是_,且非分隔符字符全为小写 → snake case;否则为undefined - 含
-:验证所有分隔符都是-,且非分隔符字符全为小写 → kebab case;否则为undefined
- 含
- 无分隔符时检查大小写规则:
- 首字母大写:验证后续所有大写字母的前一个字符为小写,且不是全大写字符串 → Pascal case;否则为undefined
- 首字母小写:验证后续所有大写字母的前一个字符为小写 → camel case;否则为undefined
修正后的代码
#include <stdio.h> #include <ctype.h> int main() { int n; scanf("%d", &n); getchar(); // 读取换行符,避免干扰后续输入 for (int i = 0; i < n; i++) { int k; char word[100]; // 可根据需求调整长度,或动态分配内存 scanf("%d %s", &k, word); // 标记分隔符相关格式的可能性 int is_snake = 1; int is_kebab = 1; int has_underscore = 0; int has_hyphen = 0; // 检查分隔符和小写规则 for (int j = 0; j < k; j++) { if (word[j] == '_') { has_underscore = 1; is_kebab = 0; } else if (word[j] == '-') { has_hyphen = 1; is_snake = 0; } else if (!islower(word[j])) { is_snake = 0; is_kebab = 0; } } if (has_underscore && is_snake) { printf("snake case\n"); continue; } if (has_hyphen && is_kebab) { printf("kebab case\n"); continue; } // 无分隔符,检查Pascal/Camel格式 int is_pascal = 1; int is_camel = 1; if (isupper(word[0])) { is_camel = 0; // 验证Pascal规则:大写字母前必须是小写,且不全为大写 for (int j = 1; j < k; j++) { if (isupper(word[j])) { if (!islower(word[j-1])) { is_pascal = 0; break; } } else if (!islower(word[j])) { is_pascal = 0; break; } } // 排除全大写情况 int all_upper = 1; for (int j = 0; j < k; j++) { if (islower(word[j])) { all_upper = 0; break; } } if (all_upper) is_pascal = 0; if (is_pascal) { printf("pascal case\n"); continue; } } else { is_pascal = 0; // 验证Camel规则:大写字母前必须是小写 for (int j = 1; j < k; j++) { if (isupper(word[j])) { if (!islower(word[j-1])) { is_camel = 0; break; } } else if (!islower(word[j])) { is_camel = 0; break; } } if (is_camel) { printf("camel case\n"); continue; } } // 所有格式均不匹配 printf("undefined case style\n"); } return 0; }
代码说明
- 优先验证snake和kebab格式,确保分隔符统一且非分隔符全为小写
- 验证Pascal和camel格式时,严格检查大小写分布规则,排除全大写等异常情况
- 输入处理采用
scanf("%d %s"),避免gets的安全问题
内容的提问来源于stack exchange,提问作者Fateme
相关产品推荐
相关产品推荐

