C语言strtok函数拆分字符串时忽略空元素的问题及解决
strtok无法识别空字符串的问题分析与修复
问题成因
strtok的核心设计就是忽略连续的分隔符,它的工作流程是:
- 首次调用时,跳过字符串开头的所有分隔符,找到第一个非分隔符字符作为token的起始位置
- 从该位置开始,直到遇到下一个分隔符,将分隔符替换为
\0,返回当前token的指针 - 后续调用
strtok(NULL, delim)时,会从上次替换\0的位置继续,同样先跳过所有连续的分隔符,再找下一个token
所以当处理"a--b-c"这类包含连续分隔符的字符串时,strtok会直接跳过中间的连续'-',不会生成空字符串的token,导致你只得到"a"、"b"、"c"三个结果。
修复方案
由于strtok的特性无法满足识别空token的需求,需要自行实现一个支持该功能的字符串拆分函数,以下是示例实现:
#include <stdio.h> #include <string.h> #include <stdlib.h> char** split(const char* str, const char* delim, int* count) { *count = 0; int str_len = strlen(str); int delim_len = strlen(delim); if (delim_len == 0) return NULL; // 先统计token的总数量 const char* p = str; while (*p) { (*count)++; const char* next = strstr(p, delim); if (next == NULL) break; p = next + delim_len; } // 分配内存存储所有token指针 char** tokens = malloc((*count) * sizeof(char*)); if (!tokens) return NULL; // 逐个提取并复制token p = str; int idx = 0; while (*p) { const char* next = strstr(p, delim); int token_len; if (next == NULL) { token_len = strlen(p); } else { token_len = next - p; } // 为单个token分配内存并复制内容 tokens[idx] = malloc(token_len + 1); strncpy(tokens[idx], p, token_len); tokens[idx][token_len] = '\0'; idx++; if (next == NULL) break; p = next + delim_len; } return tokens; } int main() { char str[] = "a--b-c"; char* delim = "-"; int count; char** tokens = split(str, delim, &count); if (tokens) { for (int i = 0; i < count; i++) { printf("element is: =====%s===== \n", tokens[i]); free(tokens[i]); } free(tokens); } return 0; }
这个函数通过strstr逐个定位分隔符的位置,即使两个分隔符连续(中间无有效字符),也会生成长度为0的空字符串token,运行后会输出你预期的"a"、""、"b"、"c"四个结果。
内容的提问来源于stack exchange,提问作者Leonardo
相关产品推荐
相关产品推荐

