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... }
关键修正说明
- 强制添加终止符:每次用
strncpy后手动设置'\0',既保证字符串正确终止,又避免了缓冲区溢出(特意预留了一个字节给终止符)。 - 正确使用strtok_r:第一次调用后,后续调用传
NULL作为第一个参数,strtok_r会通过rest自动处理剩余字符串,不需要手动复制rest回原数组。 - 初始化数组:用
memset把args整个清零,彻底消除未初始化区域的垃圾值影响。 - 安全处理换行符:先判断字符串长度和末尾字符,再替换换行符,避免空输入时
strlen(comd)-1为负数导致数组越界。
内容的提问来源于stack exchange,提问作者Qaisar Mateen
相关产品推荐
相关产品推荐

