如何用strtok()在C语言词法分析器中拆分输入字符串为Token流
如何用strtok()实现C语言词法分析中的类型分词
你的需求是把混合了字母、数字、符号的字符串按字符类型拆分,比如printf1234=---abc拆成printf、1234、=、---、abc,但原代码里只把空格作为分隔符,这显然没法满足需求——因为strtok本身是基于固定分隔符集合工作的,它没办法自动识别字符类型的变化。不过我们可以通过预处理字符串的方式,让strtok能完成这个任务。
问题分析
strtok的核心逻辑是:把字符串中属于分隔符集合的字符替换成\0,然后返回分段的指针。但你的需求不是按特定字符分割,而是按「字符类别」分割——比如字母和数字之间、数字和符号之间、符号和字母之间都需要分割。所以我们需要先在这些类型变化的位置插入一个统一的分隔符,再用strtok拆分。
解决方案步骤
- 判断字符类型:先写一个辅助函数,区分字符是字母、数字还是符号;
- 预处理字符串:遍历输入字符串,当相邻两个字符类型不同时,插入一个分隔符(比如
|,只要是输入中不会出现的字符就行); - 用strtok拆分:以插入的分隔符为参数,调用strtok拆分预处理后的字符串。
修改后的代码示例
#include <stdio.h> #include <string.h> #include <ctype.h> // 判断字符类型:0=字母,1=数字,2=符号 int get_char_type(char c) { if (isalpha(c)) { return 0; } else if (isdigit(c)) { return 1; } else { return 2; } } int main() { char input_string[100]; char processed_str[200]; // 预留足够空间存放插入的分隔符 char *token; int i = 0, j = 0; // 替换不安全的gets,用fgets更可靠 printf("Enter a string: "); fgets(input_string, sizeof(input_string), stdin); // 去掉fgets自动读取的换行符 input_string[strcspn(input_string, "\n")] = '\0'; // 预处理字符串:在类型变化处插入分隔符'|' if (input_string[0] != '\0') { processed_str[j++] = input_string[i]; int prev_type = get_char_type(input_string[i++]); while (input_string[i] != '\0') { int curr_type = get_char_type(input_string[i]); if (curr_type != prev_type) { processed_str[j++] = '|'; // 插入分隔符 } processed_str[j++] = input_string[i++]; prev_type = curr_type; } processed_str[j] = '\0'; // 字符串结束符 } // 用strtok拆分预处理后的字符串 token = strtok(processed_str, "|"); while (token != NULL) { printf("%s\n", token); token = strtok(NULL, "|"); } return 0; }
代码说明
- 字符类型判断:借助
ctype.h里的isalpha和isdigit函数,快速区分字母、数字,剩下的字符统一归为符号类; - 字符串预处理:遍历原字符串时,每检测到相邻字符类型不同,就插入
|分隔符,比如printf1234=---abc会被处理成printf|1234|=|---|abc; - 替换不安全函数:
gets存在缓冲区溢出风险,改用fgets读取输入,同时用strcspn去掉多余的换行符; - strtok拆分:此时以
|为分隔符,strtok就能精准拆分出我们需要的各个token。
测试效果
输入printf1234=---abc,程序会输出:
printf 1234 = --- abc
内容的提问来源于stack exchange,提问作者Sara
相关产品推荐
相关产品推荐

