C语言使用scanf的while循环输入多字符时打印重复问题如何解决
问题原因
- 首先是标准I/O的缓冲机制:默认情况下
stdin和stdout都是行缓冲模式。stdin会等待用户按下回车键才会把整行输入批量送入输入缓冲区,而末尾不带换行符的printf内容会暂存在stdout缓冲区,不会立刻显示到屏幕上。 - 其次是清屏时机错误:你现有代码的执行顺序是「打印本次内容→读取下一个字符→立刻清屏」,多字符输入时
scanf可以直接从缓冲区读取到下一个字符,不需要等待用户输入,刚打印还没来得及刷新到屏幕的内容会被直接清掉,残留的缓冲区内容就会和下一轮的打印内容错位,出现提示行跑到CallList前面的问题。 - 另外
scanf(" %c", &c)前的空格会自动跳过所有空白字符,所以输入的多个非空白字符会被连续读取,符合你每个字符生成一个数字的需求,这部分逻辑本身没有问题。
修复方案
调整执行顺序,先清屏再打印当前轮次的内容,同时手动刷新输出缓冲区保证内容立刻显示,修复后的参考代码如下:
#include <stdio.h> #include <stdlib.h> int main(void){ char c; const char quit = 'q'; int random; srand(1063); // 初始界面 system("clear"); printf("CallList: \n"); printf("enter any key for call (q to quit, no enter): "); fflush(stdout); // 强制刷新输出,提示立刻显示 scanf(" %c", &c); while (c != quit){ if (c != '\n') { random = rand() % 75 + 1; // 此处执行若干自定义函数 } // 先清屏,再打印当前轮次内容 system("clear"); printf("CallList: I%d U%d U%d L1", random, random + 33, random + 30); // 模拟示例的呼叫列表打印逻辑 printf("\n"); printf("enter any key for call (q to quit, no enter): "); fflush(stdout); // 强制刷新输出,避免提示滞留在缓冲区 scanf(" %c", &c); } system("clear"); printf("Goodbye! \n"); exit(0); }
如果你需要实现提示中描述的「无需按回车就响应单个按键」的效果,还需要修改终端的输入模式:Linux/macOS下可以用tcgetattr/tcsetattr将终端改为非规范模式,Windows下可以直接调用conio.h中的_getch()函数读取无缓冲的按键输入,无需等待回车。
内容的提问来源于stack exchange,提问作者Cheetos
相关产品推荐
相关产品推荐

