You need to enable JavaScript to run this app. C语言strtok分词中如何获取当前处理token的前一个token
优惠活动
大模型
产品
解决方案
定价
更多

C语言strtok分词中如何获取当前处理token的前一个token

C语言分词时获取前一个相邻Token的实现

核心实现思路

不需要维护复杂的全量历史分词计数器:只有当需要保留N步之前的多段分词结果时,才需要用固定大小的环形数组做存储。当前需求仅需获取当前token的紧邻前序结果,仅需单独维护一个prev_word指针,每轮遍历更新即可:

  • 初始化prev_word为NULL,代表当前还没有处理过任何分词
  • 每当取出一个当前分词word时,prev_word中存的就是刚好和当前token相邻的上一个分词
  • 当前token的业务逻辑处理完成后,将当前word赋值给prev_word,再去取下一个分词,保证下一轮循环时的相邻关系正确

原代码的待补全问题

  • 未校验命令行参数数量,直接读取argv[2]会触发非法内存访问
  • 未判断fopen的返回值,文件不存在/无权限时会直接操作空指针崩溃
  • 未保存历史分词指针,遇到(时无法获取其前面的相邻分词
  • 逻辑冗余:进入分词循环时已经保证word != NULL,if判断里重复的空值判断没有意义
  • 代码未闭合:缺少循环收尾、文件关闭的逻辑,直接编译会报语法错误

可运行的修改后代码

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
    // 增加参数合法性校验
    if (argc < 3) {
        printf("使用方式: %s 输入文件路径\n", argv[0]);
        return 1;
    }
    char line[1000];
    char *delimeters = ".,; \t\n";
    FILE *input = fopen(argv[2], "r");
    // 增加文件打开状态校验
    if (input == NULL) {
        perror("打开输入文件失败");
        return 1;
    }

    // 跨整文件分词场景:prev_word 定义在循环外;如果按行独立分词则定义在循环内
    // char *prev_word = NULL;
    while (fgets(line, 1000, input) != NULL)
    {
        char *prev_word = NULL; // 按行独立分词,每一行重置前序指针
        char *word = strtok(line, delimeters);

        while (word != NULL)
        {
            // 当前处理到的token是(时,prev_word就是它前面紧邻的分词
            if (strcmp(word, "(") == 0)
            {
                printf("Enters IF 3\n");
                // 边界判断:如果行首就是(,prev_word为NULL,避免空指针访问
                if (prev_word != NULL) {
                    printf("括号前的相邻分词: %s\n", prev_word);
                }
                // 原有逻辑:取括号后面的token作为方法名
                char *method_name = strtok(NULL, delimeters);
                if (method_name != NULL) {
                    printf("Method %s\n", method_name);
                }
            }
            // 更新前序指针,供下一个token使用
            prev_word = word;
            // 取下一个分词
            word = strtok(NULL, delimeters);
        }
    }
    fclose(input);
    return 0;
}

关键注意事项

  • strtok返回的指针直接指向栈上的line数组内存,只要当前行的分词流程没有结束,prev_word指向的字符串内容不会失效,不需要额外申请内存拷贝内容
  • 如果你的分词规则是跨换行连续处理(即换行不打断分词的相邻关系),只需要把prev_word的定义移动到外层逐行读取的循环外面,不要每读一行就重置为NULL
  • 做边界判断:如果某行的第一个token就是匹配的(,此时prev_word为NULL,一定要做空值判断,避免空指针读写导致程序崩溃

内容的提问来源于stack exchange,提问作者AxelCagira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 16:15:03