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

C语言strtok_r函数分词后出现垃圾值的问题求助

解决C语言strtok_r拆分字符串出现垃圾值的问题

问题根源

  • 缺少字符串终止符:strncpy(args[i], tok, strlen(tok)) 仅复制了tok的有效字符,但未在末尾添加'\0'。strncpy不会自动补终止符(除非源字符串长度小于目标缓冲区),导致args中的字符串没有正确终止,printf输出时会读取内存中后续的垃圾数据。
  • 错误复用原字符串:循环里执行strcpy(comd, rest)完全多余,还会干扰strtok_r的上下文管理——strtok_r本来就通过rest指针记录下一次拆分的位置,不需要手动覆盖原字符串。
  • 未初始化数组:局部数组args默认包含随机垃圾值,即便复制了正确字符,未覆盖的区域仍可能影响输出。

修正后的代码

//some code above...
printf("\nEnter command: ");
fgets(comd, 20, stdin);
printf("\nrecived: %s\n", comd);

// 安全处理fgets读取的换行符,避免空输入越界
size_t len = strlen(comd);
if (len > 0 && comd[len-1] == '\n') {
    comd[len-1] = '\0';
}

if(strcmp(comd, "exit") != 0 && strcmp(comd, "EXIT") != 0)
{
    int arg_count = strocc(comd, ' '); // 空格数+1是总参数个数
    char* rest;
    char args[arg_count + 1][15];
    memset(args, 0, sizeof(args)); // 初始化数组,清除垃圾值
    
    // 第一次拆分命令
    char* tok = strtok_r(comd, " ", &rest);
    if (tok != NULL) {
        // 复制时预留终止符位置,防止缓冲区溢出
        strncpy(args[0], tok, sizeof(args[0]) - 1);
        args[0][sizeof(args[0]) - 1] = '\0';
    }

    printf("\ncommand: %s Arguments: %s  Total arguments: %d\n", args[0], rest, arg_count);

    int i = 1;
    // 循环拆分剩余参数,无需操作原字符串
    while ((tok = strtok_r(NULL, " ", &rest)) != NULL && i <= arg_count)
    {   
        strncpy(args[i], tok, sizeof(args[i]) - 1);
        args[i][sizeof(args[i]) - 1] = '\0';
        printf("%s, (%d)\n", args[i], i);
        i++;
    }

    //some more code...
}

关键修正说明

  1. 强制添加终止符:每次用strncpy后手动设置'\0',既保证字符串正确终止,又避免了缓冲区溢出(特意预留了一个字节给终止符)。
  2. 正确使用strtok_r:第一次调用后,后续调用传NULL作为第一个参数,strtok_r会通过rest自动处理剩余字符串,不需要手动复制rest回原数组。
  3. 初始化数组:用memset把args整个清零,彻底消除未初始化区域的垃圾值影响。
  4. 安全处理换行符:先判断字符串长度和末尾字符,再替换换行符,避免空输入时strlen(comd)-1为负数导致数组越界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 02:17:46