Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
265 views
in Technique[技术] by (71.8m points)

c - Why getch() returns before press any key?

int main(int argc, char *argv[], char *env[])
{
    printf("Press any key to exit.
");
    getch();
    return 0;
}

According to the man page,

getch should wait until any key is pressed

...but in fact it returns directly before press any key. (The value returned is -1).

Why?


Update

I'm on Linux. How can I implement Press any key to exit., if not using getch()?

getchar() will only return after press Enter, it's not what I want.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

On Linux, getch() is probably the curses function, which is quite different from the Windows-specific function of the same name. curses (ncurses) is probably overkill for what you want to do.

The simplest approach would be to wait until the user presses Enter, which you can do like this:

int c;
printf("Press <enter> to quit: ");
fflush(stdout);
while ((c = getchar()) != '
' && c != EOF) {
    /* nothing */
}

If you really want the user to be able to press any key, not just Enter, you can do something like this:

system("stty cbreak -echo");
getchar();
system("stty cooked echo");

The second stty is intended to restore the tty to reasonable settings (it should really restore them to whatever they were, but saving and restoring the state is a little more complicated). There are probably cleaner ways to do that (using whatever library functions the stty program itself uses).

EDIT: Reading a single character without waiting for Enter is a frequently asked question. In fact, it's question 19.1 in the comp.lang.c FAQ.

EDIT2: I haven't done much work with curses recently, but I just did some playing around with it. It appears that getch() won't work unless you first call initscr() -- and initscr() clears the screen. curses is intended for use with applications like text editors that need full control of the display. There may be a way to use getch() without taking control of the screen, but I haven't found it.

The system("stty ...") kludge might actually be the best approach.

EDIT3: The termios solution in the other answer is probably the best (system("stty ...") is simpler, but invoking an external program feels like overkill.

As for the OP's comment "I can't believe Press any key to exit. is so troublesome to do in c", yes, that does seem odd -- but on further thought there are valid reasons for it.

Take a look at the programs installed on a typical Unix or Linux system. I think you'll find that very few of them require this kind of input (waiting for a single keypress).

A lot of programs work with command line arguments and data read from files or from stdin. Anything the user types is input data, not commands or responses to prompts.

Some programs do ask for confirmation for some actions (installers like apt-get and cpan often do this) -- but they usually read a line of input and check the first character. Or, for some drastic actions, they might require you to type the whole word "yes" followed by Enter (you don't want to reformat your hard drive because you accidentally hit a key).

Of course a lot of programs (text editors, file viewers) read single-character non-echoing input, but such programs tend to be curses-based; they take control of the entire terminal window.

Finally, a number of programs have GUI interfaces (web browsers, etc.); they probably don't even read from stdin.

Most production Unix programs don't use or need Press any key to exit prompts. They just do their jobs, often silently, and then terminate so you can do the next thing. The need exists largely for relatively elementary programs, such as homework assignments. Not that there's anything wrong with homework assignments, but the system as a whole isn't primarily designed to support such usage.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...