4

I'm trying to get a single character input from the user without the user having to press enter. I've tried this:

#include <stdio.h>

int main() {
    int input;

    for (;;) {
        input = getchar();
        printf("%d\n", input);
    }
}

But not only does the user need to press enter, it also registers two presses (the input character and the newline character) ie:

$ ./tests
a
97
10
c
99
10

Since I will always expect exactly one character input from the user, and want this character as either a char or an int, how can I get the character without waiting for a \n.

I also tried using fgets, but because I'm in a loop waiting for user input, that just continously executes the printf without blocking until input.

My expected output would be:

a97
b98
...

NB: I'm currently on OSX but I'm happy with a solution that applies to either OSX or Linux.

Juicy
  • 11,840
  • 35
  • 123
  • 212
  • 3
    What operating system are you working on? – syntagma Sep 25 '15 at 12:12
  • This is possible but we're moving outside of the realm of standard C for that. The way to do this depends on your operating system, so we need to know your operating system to proceed. – fuz Sep 25 '15 at 12:13
  • 6
    Take a look on [http://stackoverflow.com/questions/7469139/what-is-equivalent-to-getch-getche-in-linux](http://stackoverflow.com/questions/7469139/what-is-equivalent-to-getch-getche-in-linux) – Missu Sep 25 '15 at 12:16
  • This will probably involve `tcgetattr`/`tcsetattr`. – melpomene Sep 25 '15 at 12:16
  • You can use [`getch`](http://linux.die.net/man/3/getch) form [ncurses](http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/intro.html#WHATIS) – janisz Sep 25 '15 at 12:16

2 Answers2

4

I have recently needed exactly the same feature and I have implemented it in the following way:

#include <stdlib.h>

char c;

system("/bin/stty raw");
c = tolower(getchar());
system("/bin/stty cooked");

Looking at man stty, I think it should work on both Linux and Mac OS X.

EDIT: So your program would look like (you would need to add a signal handler to it):

#include <stdlib.h>
#include <stdio.h>

int main() {
    int input;

    for (;;) {
        system("/bin/stty raw");
        input = getchar() - '0';
        printf("%d\n", input);
        system("/bin/stty cooked");
    }
    return 0;
}
syntagma
  • 23,346
  • 16
  • 78
  • 134
0

If you want to press enter only at the end of one command you can use read (2) from the file descriptor 0.

char buff[1025];

int ret = read(0, buff, 1024);
buff[ret] = '\0';
albttx
  • 3,444
  • 4
  • 23
  • 42