C语言如何用strtok分割字符串并统计令牌总数?
strtok分割方案的适用性分析
从你给出的#分隔的结构化文本场景来看,strtok可以满足基础分割需求,但不算通用场景下的最优方案,具体要结合你的使用条件判断:
- 如果你满足以下所有条件,用strtok完全没问题:
- 单线程运行,不需要同时分割多个字符串
- 不需要保留原字符串的完整内容(strtok会修改原串,把分隔符替换为
\0) - 不存在连续
#代表空字段的场景(strtok会自动跳过连续的分隔符,忽略空字段)
- 如果不满足以上条件,更推荐替代方案:
- 多线程场景用
strtok_r,这是strtok的可重入版本,线程安全,不会出现多字符串分割互相干扰的问题 - 需要高精度匹配空字段、不想修改原串的场景,建议自己实现遍历分割逻辑,灵活性更高
- 多线程场景用
令牌总数的统计方法
有两种常用的实现思路,你可以根据自己的需求选择:
方法1:使用strtok分割时直接计数
优势是可以顺便完成令牌的提取逻辑,代码实现简单,和strtok的空字段处理逻辑完全一致:
#include <stdio.h> #include <string.h> int main() { char line_buf[1024]; int total = 0; const char delim[] = "#"; // 打开你的文本文件 FILE *fp = fopen("your_file.txt", "r"); if (!fp) { perror("文件打开失败"); return 1; } // 逐行读取处理 while (fgets(line_buf, sizeof(line_buf), fp)) { // 移除fgets读取的末尾换行符 line_buf[strcspn(line_buf, "\n")] = '\0'; // 跳过空行 if (line_buf[0] == '\0') continue; char *token = strtok(line_buf, delim); while (token != NULL) { total++; // 这里可以加你对每个令牌的处理逻辑 token = strtok(NULL, delim); } } fclose(fp); printf("总令牌数:%d\n", total); return 0; }
方法2:直接遍历统计分隔符数量(性能更高)
不需要修改原字符串,也不需要调用库函数,执行效率更高,适合只需要统计总数不需要提取令牌的场景:
- 保留空字段的统计逻辑(连续
#算多个字段):
int count_tokens(const char *str, char delim) { if (str == NULL || *str == '\0') return 0; int cnt = 1; while (*str) { if (*str == delim) cnt++; str++; } return cnt; }
- 忽略空字段的统计逻辑(和strtok行为一致):
int count_tokens_skip_empty(const char *str, char delim) { if (str == NULL || *str == '\0') return 0; int cnt = 0; int in_token = 0; while (*str) { if (*str != delim && !in_token) { cnt++; in_token = 1; } else if (*str == delim) { in_token = 0; } str++; } return cnt; }
逐行读取内容后调用对应函数累加计数即可。
内容的提问来源于stack exchange,提问作者ojihane
相关产品推荐
相关产品推荐

