1

I'm writing a menu driven program with a switch statement and while loop. My prof wants us to include "Press any key to continue..." and says to use getchar() for this. He says we will lose points if it requires us to press enter, which is what happens for me when I use the getchar().

I have seen many posts about using getch() with , however this is not working because I am using a C program compiled and executed with cygwin.

Thanks in advance

EDIT Updating since I have not seen any answer for this specific question using Unix/Linux... Emailed my prof and he got back to me with this...

"Unix/Linux issues. The keyboard input/output is buffered, i.e., your program might not get the character immediately after a user presses a key. Usually, the Operating System (OS) will send characters pressed after an ENTER key is pressed. If you want your program to get the character immediately after the user pressed it, run the following command in your shell (command window or Terminal). You only need to run it once after you first open your shell stty -icanon min 1

I did this command in the shell before compiling and it still didn't work.

I then used getchar(); twice in a row since a scanf was used previously and doesn't consume the enter used and passes it to the first getchar();

Now it works and I can press ANY key to continue...

  • 1
    So are you required to use `getchar()`? Or any input method? – Jacob Feb 18 '20 at 03:03
  • He doesn't require us to use getchar(), this is just the method he suggests. – Justin Frossard Feb 18 '20 at 03:05
  • I'm assuming you will need to submit this as an assignment. Before going to the trouble of finding a workaround, will it be compiled with Cygwin? – Jacob Feb 18 '20 at 03:29
  • Yes, the code is demonstrated in a lab and looked at by the professor. Yes it is compiled with Cygwin and so getch() will not work in this case, but getch() is the only other solution I've been able to find. – Justin Frossard Feb 18 '20 at 03:34
  • You could try `scanf`, `fgetc(stdin)` / `fgetc(stdin)` or try playing with `fgets` with size as1 or 0. – Jacob Feb 18 '20 at 03:35
  • Does this answer your question? [setvbuf not able to make stdin unbuffered](https://stackoverflow.com/questions/10247591/setvbuf-not-able-to-make-stdin-unbuffered) – user1934428 Feb 14 '22 at 10:23
  • Couldn't you read directly from `/dev/tty` instead from stdin? Processing stdin seems to be a poor choice anyway. Think about someone wanting to use your program by redirecting stdin to a file. Asking for a "keypress" does not make sense then. – user1934428 Feb 14 '22 at 10:25

1 Answers1

1

For Linux I use the following code.

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int getch (void)
{
// Declare variables.
    int c = {0};
    struct termios oldt = {0};
    struct termios newt = {0};

// Get terminal attributes.
    tcgetattr(STDIN_FILENO, &oldt);
// Store attributes.
    newt = oldt;
// Set terminal to non-buffered.
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
// Get user input.
    c = getchar();
// Reset terminal attributes.
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);

// Return character.
    return(c);
}

For Windoze, just use #include <conio.h>.

Deanie
  • 2,316
  • 2
  • 19
  • 35