目录
什么是 ReadConsoleA?
它长什么样?
怎么用它?
它跟 std::cin 有什么不一样?
注意事项
什么是 ReadConsoleA?
ReadConsoleA 是一个 Windows API 函数,用来从控制台读取用户输入。想象一下,你用 GetStdHandle(STD_INPUT_HANDLE) 拿到了键盘的“钥匙”,现在你需要一个工具来“打开键盘的门”,读取用户敲进去的文字——这个工具就是 ReadConsoleA。
它的全称是 "Read Console A",其中的 "A" 表示该函数是以 ANSI(美国国家标准协会编码)格式读取数据的版本。
-
Read":表示这是一个读取操作。
-
"Console":表示操作的是控制台(Console),即命令行界面(CLI)。
-
"A":表示函数的参数是以 ANSI 格式进行编码的。Windows 为字符串处理提供了两个版本的 API:一个是以 ANSI 字符集(单字节字符)处理字符串,另一个是以 Unicode 字符集(双字节字符)处理字符串。以 "A" 结尾的函数(例如
ReadConsoleA
)使用 ANSI 编码,"W" 结尾的函数(例如ReadConsoleW
)使用 Unicode 编码。
它有点像 C++ 的 std::cin,但更底层,直接跟 Windows 系统打交道。
它长什么样?
在代码里,ReadConsoleA 的样子是这样的:
BOOL ReadConsoleA(
HANDLE hConsoleInput, // 键盘的“钥匙”
LPVOID lpBuffer, // 放输入的“箱子”
DWORD nNumberOfCharsToRead, // 箱子最多装多少字符
LPDWORD lpNumberOfCharsRead, // 记录实际装了多少
LPVOID pInputControl // 先不管,写 NULL
);
别被这些参数吓到,我一个个解释:
-
HANDLE hConsoleInput: 这是你用 GetStdHandle(STD_INPUT_HANDLE) 拿到的键盘钥匙。
-
LPVOID lpBuffer: 一个“箱子”,用来装用户输入的文字。可以用 char 数组代替。
-
DWORD nNumberOfCharsToRead: 告诉函数“我的箱子最多能装多少字符”,防止装不下。
-
LPDWORD lpNumberOfCharsRead: 一个变量的地址,函数会把“实际装了多少字符”写在这里。
-
LPVOID pInputControl: 一个高级选项,我们暂时用不到,直接写 NULL。
返回的是 BOOL(真/假),成功返回 TRUE,失败返回 FALSE。
怎么用它?
假设你想让用户输入一些文字,然后把这些文字存起来,我们可以这样写:
#include <windows.h>
int main() {
// 1. 拿到键盘的“钥匙”
HANDLE keyboard = GetStdHandle(STD_INPUT_HANDLE);
if (keyboard == INVALID_HANDLE_VALUE) {
return 1; // 钥匙坏了,退出
}
// 2. 准备一个箱子装输入
char box[100]; // 最多装 100 个字符
DWORD how_many_read; // 记录实际读了多少
// 3. 用钥匙开门,读取输入
ReadConsoleA(keyboard, box, 100, &how_many_read, NULL);
// 4. 在箱子里加个结束标志
box[how_many_read - 2] = '\0'; // 去掉回车换行
// 5. 把箱子里的东西显示出来
HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleA(screen, box, strlen(box), &how_many_read, NULL);
return 0;
}
一步步解释:
-
拿到钥匙:
-
用 GetStdHandle(STD_INPUT_HANDLE) 拿到键盘的钥匙,存在 keyboard 里。
-
-
准备箱子:
-
char box[100] 是一个数组,就像一个能装 100 个字符的箱子。
-
DWORD how_many_read 是一个计数器,记录实际读了多少。
-
-
读取输入:
-
ReadConsoleA 用键盘钥匙“开门”,等着用户输入文字。
-
用户输入完后按 Enter,文字就装进 box 里,how_many_read 会告诉你装了多少字符。
-
-
处理箱子:
-
用户按 Enter 时,输入会多出两个字符(回车 \r 和换行 \n),所以我们减掉它们,把 box 变成普通字符串。
-
-
显示结果:
-
用 WriteConsoleA 把 box 里的内容输出到屏幕上。
-
运行这个程序,你可以输入一些文字(比如“Hi”),按 Enter 后,屏幕会显示“Hi”。
它跟 std::cin 有什么不一样?
-
std::cin 是 C++ 的高级工具,简单好用:
std::string text;
std::cin >> text;
-
但它只读到空格就停了,而且你没法控制细节。
-
ReadConsoleA 更底层:
-
它会读整行(直到用户按 Enter)。
-
你可以用它做更复杂的事,比如读取特殊按键(需要额外设置)。
-
注意事项
-
箱子大小:
-
如果用户输入超过 100 个字符(box 的大小),程序可能会出问题。所以 nNumberOfCharsToRead 要跟箱子大小匹配。
-
-
回车换行:
-
ReadConsoleA 会把 \r\n(回车和换行)也读进来,how_many_read 会包括这两个字符。所以我们用 box[how_many_read - 2] = '\0' 把它们去掉。
-
-
检查成功:
-
最好检查 ReadConsoleA 的返回值:
-
if (!ReadConsoleA(keyboard, box, 100, &how_many_read, NULL)) {
return 1; // 出错了
}