Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ win api readConsole()_C++_Windows_Winapi - Fatal编程技术网

C++ win api readConsole()

C++ 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

我正在尝试使用winapi
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);