虽然Question A被标记为重复,但引用的Question B and its answers仅解决部分问题:重定向STDIN时。因此,当STDIN未被重定向时,我再次问Question A同样的问题。
我的问题:当STDIN未重定向时,如何确定STDIN中的可用大小?请不要只使用PeekConsoleInput
回答,还要包含一个示例,因为如果可能的话,我没有找到如何使用它来完成工作的示例。
Question A and its answers确实提到过"输入事件和字符之间没有一对一的对应关系#34;这就是为什么我认为PeekConsoleInput
不是这个问题很好的解决方案,因为函数实际上是查看事件而不是输入内容。或者,也许有人可以用某种切割方式使用PeekConsoleInput
......
- 更新 - @ mikedu95 起初,我测试了mikedu95的答案,它似乎有效。 但是,睡眠功能不是我想要的。请记住,程序在收听STDIN输入时需要同时执行某些操作。因此我将其修改为以下测试代码:
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD input_record;
DWORD nb_read, nb_chars = 0, i;
string line;
printf("You have 5 seconds to type some text\n");
while (true) {
bool status = PeekConsoleInput(hStdin, &input_record, 1, &nb_read);
if (!status) {
int err = GetLastError();
cout << "err=" << err << endl;
break;
}
ReadConsoleInput(hStdin, &input_record, 1, &nb_read);
if (input_record.EventType == KEY_EVENT) {
KEY_EVENT_RECORD record = input_record.Event.KeyEvent;
if (record.bKeyDown) {
if (record.uChar.AsciiChar != '\r') {
line += record.uChar.AsciiChar;
cout << record.uChar.AsciiChar;
cout.flush();
} else {
cout << endl << "got line: " << line << endl;
line = "";
}
}
}
}
它基本上有效。然而,它引发了另一个问题:我必须处理原始密钥。它捕获上面代码中line
字符串中的每个键,包括shift键,后退空格。另外,我必须将键回到控制台,否则我看不到它正在输入文本。我真的想用cin.getline(buf, size)
来获取一行,我可以在点击&#39; Enter&#39;之前编辑该行,并处理最终输入而不是原始输入。
- Update--
另一个想法是使用cin.rdbuf()->in_avail()
,但它似乎不起作用。检查cin.rdbuf() - &gt; in_avail()的while循环永远不会返回0以外的值。事实上,内联编辑功能从未触发过,当我输入一些字符时,我看不到任何回应。
答案 0 :(得分:0)
事实上,您只是在寻找使用PeekConsoleInput的示例:
#include <Windows.h>
// Ignore events from keys like ctrl, alt, etc.
#define is_char(x) (isprint((x)) || isspace((x)))
int main(void)
{
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD input_records[50];
DWORD nb_read, nb_chars = 0, i;
printf("You have 5 seconds to type some text\n");
Sleep(5000);
PeekConsoleInput(hStdin, input_records, 50, &nb_read);
printf("read %u input events\n", nb_read);
for (i = 0; i < nb_read; i++) {
if (input_records[i].EventType == KEY_EVENT) {
KEY_EVENT_RECORD record = input_records[i].Event.KeyEvent;
if (record.bKeyDown && is_char(record.uChar.AsciiChar)) {
nb_chars += record.wRepeatCount;
}
}
}
printf("%u are chars\n", nb_chars);
return 0;
}