printf输出乱码问题:提取输入字符串首/次单词失败求助
为什么提取输入字符串的第一个和第二个单词时出现乱码?
咱们先拆解你代码里的问题,核心原因有两个:
1. scanf("%s")的截断问题+未初始化变量引发垃圾值
你用scanf("%s", username)读取输入时,%s会在遇到空格、换行这类空白字符时立刻停止读取。这意味着:
- 如果用户输入多个单词(比如
start task),username里只会存第一个单词start,剩下的task还留在输入缓冲区里,后续逻辑根本拿不到第二个单词; - 如果用户输入单个单词(比如
exit、jobs或者随便一个单字命令),sscanf(dtm, "%s %s", first_word, second_word)只会给first_word赋值,second_word作为未初始化的局部数组,栈里默认是随机的垃圾数据,打印的时候自然就输出乱码了。
2. 局部变量未初始化的隐患
first_word和second_word是栈上的局部字符数组,C语言不会自动初始化这类变量,它们的初始值是栈里遗留的随机字节——只要sscanf没给它们赋值,打印出来的就是垃圾值。
修复方案:改用整行读取+初始化变量+检查读取状态
我给你调整了代码,解决了这些问题:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char username[50]; printf("[Enter Command]: \n"); // 用fgets读取整行输入,包含空格,避免scanf的截断问题 if (fgets(username, sizeof(username), stdin) == NULL) { perror("Failed to read input"); return 1; } // 去掉fgets附带的换行符(否则字符串末尾会多一个\n) username[strcspn(username, "\n")] = '\0'; if (strcmp("exit", username) == 0) { exit(0); } if (strcmp("jobs", username) == 0) { printf("[SERVER] No currently running jobs\n"); // 这里加个return,避免后续继续处理这个单字命令 return 0; } char dtm[50]; // 初始化数组,确保即使没被赋值也不会有垃圾值 char first_word[50] = {0}; char second_word[50] = {0}; strcpy(dtm, username); // 检查sscanf的返回值,它会告诉你成功读取了几个字段 int read_fields = sscanf(dtm, "%s %s", first_word, second_word); printf("%s", first_word); // 只有成功读取到第二个单词时才打印它 if (read_fields >= 2) { printf(" %s", second_word); } printf("\n"); return 0; }
额外注意事项
- 永远不要使用未初始化的局部变量,这是C语言里常见的bug来源;
scanf("%s")有缓冲区溢出风险,如果用户输入超过数组长度会炸栈,建议要么限制长度(比如scanf("%49s", username)),要么优先用fgets更安全;- 处理输入时一定要检查函数返回值(比如
fgets是否成功、sscanf读取了几个字段),这样能应对各种异常输入情况。
内容的提问来源于stack exchange,提问作者static
相关产品推荐
相关产品推荐

