C++ win api readConsole()
我正在尝试使用winapiC++ win api readConsole(),c++,windows,winapi,C++,Windows,Winapi,我正在尝试使用winapiReadConsole(…),我想传入一个分隔符char来停止控制台的输入。 下面的代码可以工作,但它只会停止读取\r\n上的输入。 我希望它停止读取上的控制台输入。例如 void read(char *cIn, char delim) { HANDLE hFile; DWORD charsRead; DWORD charsToRead = MAX_PATH; CONSOLE_READCONSOLE_CONTROL cReadContro
ReadConsole(…)
,我想传入一个分隔符char来停止控制台的输入。
下面的代码可以工作,但它只会停止读取\r\n
上的输入。
我希望它停止读取上的控制台输入。
例如
void read(char *cIn, char delim)
{
HANDLE hFile;
DWORD charsRead;
DWORD charsToRead = MAX_PATH;
CONSOLE_READCONSOLE_CONTROL cReadControl;
cReadControl.nLength = sizeof(CONSOLE_READCONSOLE_CONTROL);
cReadControl.nInitialChars = 0;
cReadControl.dwCtrlWakeupMask = delim;
cReadControl.dwControlKeyState = NULL;
DWORD lpMode;
// char cIn[MAX_PATH]; //-- buffer to hold data from the console
hFile = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
GetConsoleMode(hFile,&lpMode);
// lpMode &= ~ENABLE_LINE_INPUT; //-- turns off this flag
// SetConsoleMode(hFile, lpMode); //-- set the mode with the new flag off
bool read = ReadConsole(hFile, cIn, charsToRead * sizeof(TCHAR), &charsRead, &cReadControl);
cIn[charsRead - 2] = '\0';
}
我知道还有其他简单的方法可以做到这一点,但我只是想了解一些WinAPI函数以及如何使用它们
谢谢。您会发现这段代码很荒谬。这很可能是实现这一目标的唯一方法。如果您必须适应以后使用ReadFile,这是唯一不消耗更多输入的方法 大多数情况下,你根本不需要ReadConsole,你需要标准输入句柄上的ReadFile,但我离题了
char *cInptr = cIn;
do {
bool read = ReadConsole(hFile, cInptr, sizeof(TCHAR), &charsRead, &cReadControl);
if (read) cInptr += charsRead;
} while (read && charsRead > 0 && cInptr[-1] && cInptr[-1] != '.');
由于偏执,我可能有太多的测试在循环中。我不想通过查找所有谓词来确定ReadConsole契约所隐含的谓词。我看到了这个问题,并假设它很简单,但我花了最后30分钟试图找出它,最终得到了一些东西
dwCtrlWakeupMask
在CONSOLE\u READCONSOLE\u CONTROL
中的记录非常糟糕。MSDN说“一个用户定义的控制字符,用来表示读取已完成。”,但为什么它被称为mask
?为什么它是ULONG
而不是TCHAR
或类似的东西?我试着给它喂食了很多食物,但什么也没发生,所以故事中肯定有更多的东西
我在网上搜索该特定变量,并找到以下链接:
这是一个随机的Go库编码器请求帮助,答案是tab是
1,如果您想要完整的控制台输入并获得有关任何按下键的信息,就在它按下时(而不是等待VK_返回),您需要使用ReadConsoleInputReadConsole@RbMm谢谢,这很有帮助。@ilw的确,空间是代码32,太大了一点,放不进去。我将重新使用这个函数,并想写下它如何工作的更多细节。当您传递CONSOLE\u READCONSOLE\u控件结构时,nInitialChars
成员会在控制台的编辑缓冲区中保留一些输入缓冲区。当它返回时,输入将用字符替换缓冲区中光标位置的字符,并将编辑行的其余部分保留在那里。您可以扫描并编辑缓冲区,然后再次调用并将该nInitialChars
成员设置为保留,以备下次使用。如果你在一行中完成标签,你就不能把光标放在中间。如果请求BUF大小太大,比如65000字节,有没有人可以帮助我解释为什么Read控制台、RealEngEndol、Read Field(COnSOLeIIN)、写文件(CONSOLIZOUT)失败?我希望它能尽可能多地回馈给我。posix替代方案“写和读”都能很好地工作。@JaveneCPPMcGowan文档没有说,但我看到有人报告某些函数有64KB的限制。由于它是宽字符,这意味着32k元素最大可能是所有支持的。但是您可以使用比可用缓冲区更大的缓冲区—这就是您通常的做法,就像在posix上一样。只要试一个较小的缓冲区,看看会发生什么。@Adam D.Ruppe谢谢。这不能解决我的问题,但还是要谢谢你?我的问题是需要一致性。MSDN应记录此类错误。而事实上,其他人没有抱怨意味着有些事情不正常。显然,posix函数的设计没有这些限制。在posix模式下打开终端可能会解决我的问题。ReadConsole比ReadFile有一个重要的优势:它可以读取unicode字符。使用ReadConsoleW和WriteConsoleW,您可以获得宽字符,从而避免其他代码页的所有问题。@AdamD.Ruppe:根据我的经验,当出现此问题时,stdin通常连接到管道。但请注意,ReadFile是一个二进制读取器,其计数是字节,而不是ReadConsole的字符。
cReadControl.dwCtrlWakeupMask = (1 << '\t') | (1 << 0x08);
cReadControl.dwCtrlWakeupMask = (1 << 4) | (1 << 26);