调用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
相关产品推荐
相关产品推荐

