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

调用SetConsoleActiveScreenBuffer后cin/cout报错0xc0000142如何解决?

解决SetConsoleActiveScreenBuffer后cin/cout异常的问题

首先,你的问题核心在于:默认的cin/cout绑定的是程序启动时创建的原始控制台缓冲区,当你调用SetConsoleActiveScreenBuffer切换到自己创建的新缓冲区后,标准输入输出流并没有自动关联到这个新缓冲区,这就导致了输入操作时的错误(错误码0xc0000142本质是因为句柄不匹配引发的初始化/访问失败)。

修复方案:重定向标准句柄到当前活动缓冲区

你需要手动将标准输入、输出句柄重定向到当前激活的屏幕缓冲区,使用SetStdHandle函数完成这个操作。具体步骤如下:

  • 在激活新缓冲区后,调用SetStdHandle分别设置STD_INPUT_HANDLE和STD_OUTPUT_HANDLE为当前缓冲区的句柄;
  • (可选但推荐)重置cin/cout的状态,确保它们使用新的句柄工作。

下面是修改后的你的代码,加入了关键的修复部分:

#include <iostream>
#include <cstring>
#include <windows.h>
using namespace std;

int main() {
    HANDLE mhBuffer[2];
    int mCurrentBufferIndex = 0;
    COORD mSize;
    mSize.X = 120;
    mSize.Y = 30;
    CONSOLE_CURSOR_INFO cci;
    SMALL_RECT rect;
    rect.Left = 0;
    rect.Right = mSize.X - 1;
    rect.Top = 0;
    rect.Bottom = mSize.Y - 1;

    // 创建缓冲区
    mhBuffer[0] = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    SetConsoleScreenBufferSize(mhBuffer[0], mSize);
    SetConsoleWindowInfo(mhBuffer[0], TRUE, &rect);
    
    mhBuffer[1] = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    SetConsoleScreenBufferSize(mhBuffer[1], mSize);
    SetConsoleWindowInfo(mhBuffer[1], TRUE, &rect);

    cci.dwSize = 1;
    cci.bVisible = FALSE;
    SetConsoleCursorInfo(mhBuffer[0], &cci);
    SetConsoleCursorInfo(mhBuffer[1], &cci);

    // 写入内容到缓冲区
    DWORD dw;
    COORD CursorPosition = { 0,0 };
    SetConsoleCursorPosition(mhBuffer[mCurrentBufferIndex], CursorPosition);
    char str[] = "buffer";
    WriteFile(mhBuffer[mCurrentBufferIndex], str, strlen(str), &dw, NULL);
    Sleep(33);

    // 激活缓冲区
    SetConsoleActiveScreenBuffer(mhBuffer[mCurrentBufferIndex]);

    // 关键修复:重定向标准句柄到当前活动缓冲区
    SetStdHandle(STD_INPUT_HANDLE, mhBuffer[mCurrentBufferIndex]);
    SetStdHandle(STD_OUTPUT_HANDLE, mhBuffer[mCurrentBufferIndex]);

    // 重置cin/cout的状态,确保使用新句柄
    cin.clear();
    cout.clear();
    
    // 现在可以正常使用cin/cout了
    int b = 0;
    cin >> b;
    cout << "You entered: " << b << endl;

    return 0;
}

额外说明

  • 如果你频繁切换缓冲区,每次激活新缓冲区后都需要重复执行SetStdHandle的操作,因为cin/cout会持续绑定当前设置的标准句柄;
  • 另一种替代方案是直接使用Win32 API的ReadConsole和WriteConsole来操作缓冲区,这样可以完全绕过标准流,避免句柄不匹配的问题,比如用ReadConsole(mhBuffer[mCurrentBufferIndex], &inputBuffer, sizeof(inputBuffer), &dw, NULL)来替代cin输入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 18:47:35