I'm writing code where I need to get input without the user pressing ENTER. The code is basically that I need to get 4 numbers from 1-6 without the user pressing ENTER all in one line.
I tried doing so with getchar()
, but it doesn't work.
How do I do that?
Here's that part of the code:
int p1 = 0;
int p2 = 0;
int p3 = 0;
int p4 = 0;
p1 = getchar() - 48;
p2 = getchar() - 48;
p3 = getchar() - 48;
p4 = getchar() - 48;
CodePudding user response:
This is a C FAQ: 12.5 How can I read one character at a time, without waiting for the RETURN key?
To quote:
Depending on which operating system you're using and what libraries you have available, you may be able to use one (or more!) of the following techniques:
- If you can use the curses library, you can call cbreak [footnote] (and perhaps noecho), after which calls to getch will return characters immediately.
- If all you're trying to do is read a short password without echo, you may be able to use a function called getpass, if it's available. (Another possibility for hiding typed passwords is to select black characters on a black background.)
- Under classic versions of Unix, use ioctl and the TIOCGETP and TIOCSETP (or TIOCSETN) requests on file descriptor 0 to manipulate the sgttyb structure, defined in <sgtty.h> and documented in tty(4). In the sg_flags field, set the CBREAK (or RAW) bit, and perhaps clear the ECHO bit.
- Under System V Unix, use ioctl and the TCGETAW and TCSETAW requests on file descriptor 0 to manipulate the termio structure, defined in <termio.h>. In the c_lflag field, clear the ICANON (and perhaps ECHO) bits. Also, set c_cc[VMIN] to 1 and c_cc[VTIME] to 0.
- Under any operating system (Unix or otherwise) offering POSIX compatibility, use the tcgetattr and tcsetattr calls on file descriptor 0 to manipulate the termios structure, defined in <termios.h>. In the c_lflag field, clear the ICANON (and perhaps ECHO) bits. Also, set c_cc[VMIN] to 1 and c_cc[VTIME] to 0.
- In a pinch, under Unix, use system (see question 19.27) to invoke the stty command to set terminal driver modes (as in the preceding three items).
- Under MS-DOS, use getch or getche, or the corresponding BIOS interrupts.
- Under VMS, try the Screen Management (SMG$) routines, or curses, or issue low-level $QIO's with the IO$_READVBLK function code (and perhaps IO$M_NOECHO, and others) to ask for one character at a time. (It's also possible to set character-at-a-time or ``pass through'' modes in the VMS terminal driver.)
- Under other operating systems, you're on your own.
CodePudding user response:
There is no standard function for this.
There are some custom solutions e.g. https://www.cs.uleth.ca/~holzmann/C/system/ttyraw.c But your mileage may vary.
However if this kind of dynamic use of the terminal is core to your program I would recommend using ncurses or something similar.