如何对数组中的字符串分词?排查分词异常与程序崩溃问题
字符串分词问题排查与修复方案
Hey,我来帮你拆解下这个分词代码的问题~ 你遇到的两个核心问题:第一个单词数组混进了空格和其他单词字符,还有程序崩溃,其实都是分词逻辑和数组边界处理的常见坑,咱们一步步分析:
一、为什么第一个单词会混入多余字符?
你说遇到空格/制表符时没停止写入,大概率是你的代码没有正确处理“分隔符”和“单词”的状态切换,常见的错误场景有两种:
- 开头没跳过前置的空格/制表符:直接把开头的空白字符写入了第一个单词数组
- 遇到分隔符时没终止当前单词:还在继续把后面的单词字符往当前单词数组里塞
举个你可能写错的反例:
// 错误示例:没有状态切换的分词逻辑 char word1[20]; int idx = 0; for (int i=0; line[i]!='\0'; i++) { if (line[i] == ' ' || line[i] == '\t') { continue; // 只跳过,但没结束当前单词的写入 } word1[idx++] = line[i]; // 所有非空白字符都塞给word1,包括后面单词的内容 } word1[idx] = '\0';
这种写法就会导致word1里混进所有非空白字符,完全没实现分词的效果。
二、程序崩溃的核心:数组越界
你怀疑的数组越界完全正确,崩溃基本是这两个原因导致的:
- 单个单词长度超过数组容量:如果原字符串里有一个很长的单词,你的代码没做长度限制,就会把数据写到数组外面,覆盖栈上的关键数据(比如函数返回地址),直接触发崩溃
- 提取超过3个单词:如果你的代码没限制最多提取3个单词,当原字符串有超过3个单词时,会尝试往第4个不存在的单词数组里写数据,同样触发越界
三、修复后的完整代码示例
我给你写了一个符合需求的实现,解决了上面的两个问题:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_WORD_LEN 20 // 限制单个单词的最大长度,避免越界 int main() { char line[] = " hello\tworld foo bar "; // 你的测试用例,包含空格、制表符 char word1[MAX_WORD_LEN], word2[MAX_WORD_LEN], word3[MAX_WORD_LEN]; char *words[] = {word1, word2, word3}; // 用指针数组管理三个单词,方便循环处理 int word_count = 0; // 已提取的单词数 int current_char_idx = 0; // 当前单词的字符索引 int in_word = 0; // 标记是否正在写入一个单词(状态切换用) // 遍历字符串,最多提取3个单词 for (int i=0; line[i] != '\0' && word_count < 3; i++) { // 遇到分隔符(空格/制表符) if (line[i] == ' ' || line[i] == '\t') { if (in_word) { // 结束当前单词,添加字符串终止符 words[word_count][current_char_idx] = '\0'; word_count++; // 切换到下一个单词 current_char_idx = 0; in_word = 0; } continue; } // 处理非分隔符字符,且当前单词未超出最大长度 if (current_char_idx < MAX_WORD_LEN - 1) { // 留一个位置给'\0' words[word_count][current_char_idx++] = line[i]; in_word = 1; // 标记进入单词状态 } } // 处理字符串末尾的单词(如果最后不是分隔符的情况) if (in_word && word_count < 3) { words[word_count][current_char_idx] = '\0'; word_count++; } // 输出测试结果 printf("提取的单词:\n"); for (int i=0; i<word_count; i++) { printf("单词%d: %s\n", i+1, words[i]); } return 0; }
关键修复点说明
- 状态标记
in_word:用来区分当前是在空白区域还是单词区域,遇到分隔符时如果正在写单词,就及时终止当前单词并切换到下一个 - 严格的长度限制:写入单词时检查
current_char_idx < MAX_WORD_LEN - 1,确保不会超出数组边界,预留位置给字符串终止符'\0' - 单词计数限制:循环条件里加入
word_count < 3,确保只提取最多3个单词,避免越界访问不存在的单词数组
内容的提问来源于stack exchange,提问作者topcat
相关产品推荐
相关产品推荐

