C语言字符缓冲区无法清除求助:输入处理后输出重复
你的核心问题是结构体cmd没有被正确清零,导致上一次解析的残留数据影响了下一次输出,同时还有几个细节需要调整,咱们一步步来解决:
1. 结构体清零的致命错误
在parse函数末尾,你写了:
memset(&cmd, 0, sizeof(cmd));
这里cmd是Command*类型的指针,sizeof(cmd)得到的是指针本身的大小(通常是4或8字节),而非整个Command结构体的大小。这就导致结构体里的关键成员(比如tokenscounter、commandsArray的旧索引)根本没被重置,下一次循环时会在旧数据基础上继续追加,所以才会出现重复输出的情况。
修正方法:
把这行改成:
memset(cmd, 0, sizeof(*cmd));
*cmd代表指针指向的结构体实例,sizeof(*cmd)会正确计算整个结构体的字节数,这样才能将所有成员彻底重置为0。
2. 不必要的line内存操作
你在parse最后调用了:
memset(line, 0, 1024);
但line是主函数中用malloc分配的内存,马上就要被free释放,这步清零完全多余。而且如果MAX_BUFFER不等于1024,还可能引发内存越界访问,直接删掉这行即可。
3. 额外风险提示:strtok的野指针问题
你的cmd->commandsArray存储的是strtok返回的指针,这些指针指向的是line的内存空间。但主函数每次循环都会free(line),这会导致commandsArray里的指针变成野指针(指向已释放的内存)。虽然当前问题不在此,但长期来看可能引发不可预测的错误。如果需要保留这些token,建议存储时用strdup复制字符串,并在清零结构体时记得释放这些复制的内存。
修正后的parse函数关键片段
void parse(Command *cmd, char *line) { char *p = strtok (line, " \n"); while (p != NULL) { // 你的token处理逻辑... cmd->commandsArray[cmd->tokenscounter++] = p; p = strtok (NULL, " \n"); } // 你的输出逻辑... // 正确清零结构体 memset(cmd, 0, sizeof(*cmd)); // 移除不必要的memset(line, 0, 1024); }
测试验证
修正后重新运行程序,输入hello world应该只会输出一次对应内容,下一次输入也不会重复之前的结果了。
内容的提问来源于stack exchange,提问作者Austin Sharma

