Home > database >  How to read user input without pressing ENTER?
How to read user input without pressing ENTER?

Time:01-02

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.

  •  Tags:  
  • c
  • Related