Search code examples
c++windowswinapiio

ReadFile only returns after newline


I'm trying to read every character pressed in my console in realtime.
I'm using ReadFile to read from stdin, but it seems to only complete the read operation after a newline (when I press enter).
Here is my code:

    char buf[1] = { 0 };
    HANDLE stdInHandle = GetStdHandle(STD_INPUT_HANDLE), stdOutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    while (true) {
        ReadFile(stdInHandle, buf, sizeof(buf), NULL, NULL);
        WriteFile(stdOutHandle, buf, sizeof(buf), NULL, NULL);
    }

How would I read the characters pressed realtime, instead of after a newline?


Solution

  • As I've mentioned in a comment you could use SetConsoleMode to disable line-buffering:

    #include <windows.h>
    
    int main()
    {
        HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
        HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    
        // Get the current console mode
        DWORD mode;
        GetConsoleMode(hInput, &mode);
    
        // Save the current mode, so we can restore it later
        DWORD original_mode = mode;
    
        // Disable the line input mode
        mode &= ~ENABLE_LINE_INPUT;
    
        // And set the new mode
        SetConsoleMode(hInput, mode);
    
        // Then read and write input...
        for (;;)
        {
            TCHAR buffer[1];
            DWORD nread = 0;
    
            // TODO: Need to add some error checking here!
            ReadConsole(hInput, buffer, 1, &nread, nullptr);
            WriteConsole(hOutput, buffer, nread, nullptr, nullptr);
    
            // Allow some way to exit the program
            if (buffer[0] == 'q' || buffer[0] == 'Q')
            {
                break;
            }
        }
    
        // Restore the original console mode
        SetConsoleMode(hInput, original_mode);
    }