C语言拆分字符串时如何保留作为分隔符的字母字符
按大写字母拆分字符串并保留分隔符的实现方案
原方案问题分析
strtok 原生设计是会将匹配到的分隔符直接替换为\0,无法直接保留分隔符作为拆分后片段的开头,所以原写法会直接丢失所有大写字母,达不到需求。你想到的提前在每个大写字母前插入特殊分隔符再用strtok拆分的思路是完全可行的,除此之外也可以直接手动遍历字符串实现,不需要额外预处理步骤,性能更好也不需要依赖正则(C标准库没有内置正则支持,引入第三方库完全没必要)。
方案1:预插分隔符+strtok 实现(符合你提到的思路)
#include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> int main() { char original_str[] = "A89 99B0 C11D98 9"; int len = strlen(original_str); // 计算预处理后字符串长度:每个大写字母前多1个分隔符,加结束符 int new_len = len; for (int i = 0; i < len; i++) { if (isupper(original_str[i])) new_len++; } char *processed_str = malloc(new_len + 1); int pos = 0; // 填充预处理后的字符串,用原串中不存在的|作为临时分隔符 for (int i = 0; i < len; i++) { // 开头的大写字母不需要前插分隔符 if (isupper(original_str[i]) && i != 0) { processed_str[pos++] = '|'; } processed_str[pos++] = original_str[i]; } processed_str[pos] = '\0'; // 按临时分隔符拆分 char *ptr = strtok(processed_str, "|"); while(ptr != NULL) { printf("%s\n", ptr); ptr = strtok(NULL, "|"); } free(processed_str); return 0; }
方案2:手动遍历实现(更推荐,无额外开销)
不需要修改原字符串、不需要动态申请内存、也不存在strtok的不可重入问题,逻辑更简洁:
#include <stdio.h> #include <string.h> #include <ctype.h> int main() { char str[] = "A89 99B0 C11D98 9"; int len = strlen(str); int start = 0; // 从第二个字符开始遍历,第一个字符默认是片段开头 for (int i = 1; i < len; i++) { // 遇到大写字母就输出前一个片段 if (isupper(str[i])) { printf("%.*s\n", i - start, str + start); start = i; } } // 输出最后一个剩余片段 printf("%s\n", str + start); return 0; }
两种方案的输出都完全符合你要求的效果。
内容的提问来源于stack exchange,提问作者Googlebot
相关产品推荐
相关产品推荐

