1

I'm reading user input from console using ReadConsoleW () function. I would like the user to be able to input end of line character '\n' in the console, so this character will be interpreted only as a new line character, but not as the end of ReadConsoleW () input. It should look like this:

Program output: Enter your message.

User input:
One of the basic pieces of furniture, a chair is a type of seat.

Chairs vary in design.

I need it to allow the user edit his input until it's decided that the message is ready for reading, otherwise the user will be bounded by the need to edit only the last input paragraph. So:

  1. Is it possible to specify that input should not end on a new line character?
  2. If so, how to specify a character as the end of input, for example, stop reading when '$' character appears?
CoSalamander
  • 121
  • 7

1 Answers1

1

You can buffer the input by character, not by line, using SetConsoleMode:

#include <Windows.h>
#include <stdio.h>

#define MAX_SIZE 256

int main()
{
    WCHAR input[2] = { '\0' };
    WCHAR line[MAX_SIZE] = { '\0' };
    DWORD count;

    HANDLE buf = GetStdHandle(STD_INPUT_HANDLE);
    
    DWORD opts;
    GetConsoleMode(buf, &opts);
    opts &= ~ENABLE_LINE_INPUT; // buffer by character, not by line
    SetConsoleMode(buf, opts);

    do {
        lstrcatW(line, input);
        ReadConsoleW(buf, input, 2, &count, NULL);
        wprintf(L"%s", input);
    } while (input[0] != '$');

    wprintf(L"%s", line);
}

Obviously this is just a rough idea on how to do it, and in reality it may buffer more than one character at a time so the input should be larger and the $ may not be guaranteed to be held in the first character (I think, you need to read the documentation to see what really goes on). Turning off ENABLE_LINE_INPUT disables echoing the input which is why I print input after each call to ReadConsoleW.

Hope this gets you on the right track to what you were thinking of doing :).

Dominic Price
  • 1,111
  • 8
  • 19
  • Yes, it allows to finish the input immediately by entering a specified character, but it breaks the whole representation of user input in console, i.e.: 1) using end of line character is displayed in console as carriage return, but not as a new line; 2) it also doesn't remove written console characters by pressing backspace, only moving line pointer back; 3) not sure, but it still makes impossible to edit previous input after end of line character is in input. – CoSalamander Nov 26 '21 at 19:06
  • Problem №2 can be solved by putting '\n' to output when it was detected in input. It looks like a workaround tho. – CoSalamander Nov 26 '21 at 19:13
  • You can use ansi escape sequences to move up a line when backspacing a newline. At the rugby tonight so can’t demo you but if you search ‘ansi move cursor’ you might find some references. FWIW if this is more than just ‘hobbyist’ code, then you shouldn’t try and reimplement the wheel - just open a text editor (e.g GNU nano) when you need user input and save it to a temporary file, then read the output into a string. See https://stackoverflow.com/questions/14217946/how-to-open-nano-and-get-a-string-from-it-in-c for example – Dominic Price Nov 26 '21 at 20:18
  • I differently tried to re-implement the wheel, wow. Thought I was looking at VIM and just wanted some simple input and edit, I didn't came up with the idea that there is something like this. I'll read about "nano" later, that's probably what I really need. – CoSalamander Nov 26 '21 at 20:55