You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键改动说明

  1. 补全ClearScreen函数:原代码仅有声明无实现,这里补充了标准的终端清屏逻辑。
  2. 注册退出信号处理:通过SetConsoleCtrlHandler捕获Ctrl+C、窗口关闭等事件,退出前调用FlushConsoleInputBuffer清空所有未处理的输入字符。
  3. 添加手动退出逻辑:支持按ESC键退出程序,同样在退出前执行缓冲区清理。
  4. 修复变量未声明问题:补全了原代码中未声明的hStdOut全局变量。

修改后,无论通过Ctrl+C还是ESC键退出程序,终端输入行都会保持干净,不会残留之前输入的字符。

内容的提问来源于stack exchange,提问作者satk0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 17:00:05