You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

原指针在内容复制到另一数组后受影响的问题及修复方法咨询

原指针在内容复制到另一数组后受影响的问题及修复方法咨询

嘿,这个问题我太熟了!大概率是strtok这个“坑货”搞的鬼,我来给你拆解下原因,再给你几个实用的修复方案。

首先说问题出在哪:你应该是在is_ingredient_list和is_ingredient两个函数里都用了strtok来做分词吧?strtok内部用了一个静态变量来记住上次分词的位置,相当于它是全局共享的状态。当你在is_ingredient里调用strtok处理临时数组时,它会直接覆盖这个静态变量的内容,等你回到is_ingredient_list继续用strtok时,它早就忘了之前的位置,自然只能停在第一个token了,看起来就像是原指针被影响了一样。

那怎么修复呢?给你两个靠谱的办法:

  • 用可重入的分词函数替代strtok
    如果你是在POSIX系统(比如Linux、macOS)上开发,用strtok_r;如果是Windows系统,用strtok_s。这两个函数需要你自己传一个指针来保存分词的位置,每个函数用自己的位置变量,就不会互相干扰了。

    比如你的is_ingredient_list可以改成这样:

    void is_ingredient_list(char* original_str) {
        char delim[] = " "; // 这里换成你实际用的分隔符
        char* save_ptr_list; // 专门用于list函数的位置指针
        char* token = strtok_r(original_str, delim, &save_ptr_list);
        while (token != NULL) {
            is_ingredient(token);
            token = strtok_r(NULL, delim, &save_ptr_list);
        }
    }
    

    然后is_ingredient里处理临时数组时,也用自己的位置变量:

    int is_ingredient(const char* str){
        char tmp[1024];
        strncpy(tmp, str, sizeof(tmp));
        tmp[sizeof(tmp)-1] = '\0';
        char delim[] = " "; // 你的分隔符
        char* save_ptr_ingred; // 专门用于当前函数的位置指针
        char* tmp_token = strtok_r(tmp, delim, &save_ptr_ingred);
        
        while (tmp_token != NULL) {
            // 这里写你处理每个token的逻辑
            tmp_token = strtok_r(NULL, delim, &save_ptr_ingred);
        }
        return 1; // 换成你实际的返回值
    }
    
  • 手动实现分词逻辑,完全绕开strtok
    如果你不想依赖系统特定的函数,也可以自己写分词逻辑,完全不用strtok,这样就不会有状态冲突的问题了。比如在is_ingredient里这样写:

    int is_ingredient(const char* str){
        char tmp[1024];
        strncpy(tmp, str, sizeof(tmp));
        tmp[sizeof(tmp)-1] = '\0';
        char delim = ' '; // 你的分隔符,要是有多个可以加判断
        
        char* start = tmp;
        while (*start != '\0') {
            // 找到当前token的结尾
            char* end = start;
            while (*end != '\0' && *end != delim) {
                end++;
            }
            // 临时把分隔符换成'\0',拿到完整的token
            char temp = *end;
            *end = '\0';
            
            // 这里写你处理token的代码,比如判断是不是食材
            // printf("当前处理的token: %s\n", start);
            
            // 恢复分隔符(其实tmp是临时数组,不恢复也不影响)
            *end = temp;
            // 移动到下一个token的开头
            start = (*end != '\0') ? end + 1 : end;
        }
        return 1;
    }
    

总结一下,核心就是避免跨函数共享strtok的静态状态,要么用带独立状态的可重入函数,要么自己实现无状态的分词逻辑,这样原指针所在的分词流程就不会被打断了。

备注:内容来源于stack exchange,提问作者user26502233

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:19:29