Windows平台下C程序执行后清除终端输入字符的方法
解决Windows终端程序退出后残留输入字符的问题
你的问题核心是Windows终端的输入缓冲机制:程序运行时你输入的字符会被系统暂存在输入缓冲区中,但你的程序没有读取这些输入,导致缓冲区里的内容在程序退出后被终端直接回显到输入行上。
具体解决方法
要解决这个问题,需要在程序退出前清空输入缓冲区,同时确保程序能响应退出信号(比如Ctrl+C)来执行清理操作。
以下是修改后的完整代码,关键部分已标注:
#include <stdio.h> #include <Windows.h> #include <stdlib.h> // 声明全局标准输出句柄(原代码未声明) HANDLE hStdOut; // 补全ClearScreen函数实现 void ClearScreen() { COORD coordScreen = {0, 0}; DWORD cCharsWritten; CONSOLE_SCREEN_BUFFER_INFO csbi; DWORD dwConSize; if (!GetConsoleScreenBufferInfo(hStdOut, &csbi)) { return; } dwConSize = csbi.dwSize.X * csbi.dwSize.Y; if (!FillConsoleOutputCharacter(hStdOut, ' ', dwConSize, coordScreen, &cCharsWritten)) { return; } if (!GetConsoleScreenBufferInfo(hStdOut, &csbi)) { return; } if (!FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten)) { return; } SetConsoleCursorPosition(hStdOut, coordScreen); } struct Keys { unsigned int k1: 1; unsigned int k2: 1; unsigned int k3: 1; unsigned int k4: 1; }; void check_key(struct Keys* keys) { keys->k1 = 0; keys->k2 = 0; keys->k3 = 0; keys->k4 = 0; if (GetKeyState('A') & 0x8000) { keys->k1 = 1; } if (GetKeyState('S') & 0x8000) { keys->k2 = 1; } if (GetKeyState('D') & 0x8000) { keys->k3 = 1; } if (GetKeyState('F') & 0x8000) { keys->k4 = 1; } } void print_keys(struct Keys keys) { ClearScreen(); printf("K1 = %d | K2 = %d | K3 = %d | K4 = %d", keys.k1, keys.k2, keys.k3, keys.k4); printf("\n"); printf("P1 = 1"); } // 退出回调函数:处理Ctrl+C、窗口关闭等退出信号 BOOL WINAPI ConsoleHandler(DWORD dwCtrlType) { if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_CLOSE_EVENT) { // 清空输入缓冲区,清除残留按键 HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); FlushConsoleInputBuffer(hStdIn); CloseHandle(hStdIn); // 清屏并重置光标位置 ClearScreen(); CloseHandle(hStdOut); exit(0); } return FALSE; } int main () { hStdOut = GetStdHandle( STD_OUTPUT_HANDLE ); if (hStdOut == INVALID_HANDLE_VALUE) return -1; // 注册控制台退出处理函数 if (!SetConsoleCtrlHandler(ConsoleHandler, TRUE)) { printf("无法注册控制台处理函数\n"); return -1; } struct Keys keys = {0, 0, 0, 0}; while (1) { check_key(&keys); print_keys(keys); Sleep(100); // 可选:按ESC键手动退出 if (GetKeyState(VK_ESCAPE) & 0x8000) { HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); FlushConsoleInputBuffer(hStdIn); CloseHandle(hStdIn); ClearScreen(); break; } } CloseHandle(hStdOut); return 0; }
关键改动说明
- 补全
ClearScreen函数:原代码仅有声明无实现,这里补充了标准的终端清屏逻辑。 - 注册退出信号处理:通过
SetConsoleCtrlHandler捕获Ctrl+C、窗口关闭等事件,退出前调用FlushConsoleInputBuffer清空所有未处理的输入字符。 - 添加手动退出逻辑:支持按ESC键退出程序,同样在退出前执行缓冲区清理。
- 修复变量未声明问题:补全了原代码中未声明的
hStdOut全局变量。
修改后,无论通过Ctrl+C还是ESC键退出程序,终端输入行都会保持干净,不会残留之前输入的字符。
内容的提问来源于stack exchange,提问作者satk0
相关产品推荐
相关产品推荐

