I am writing a program which has a main menu, with a couple functions which I am allowing the user to access by typing in a number for one menu selections. For that, I am using _getch(). I need to be able to exit the program when the user enters the EOF key, but _getch() does not actually catch the EOF keystroke. I know I can get it to work by using getchar() instead of _getch(), but I would prefer not to have the user be forced to press enter after every function selection.
Is there a way to get _getch() to catch EOF? This is for Windows if it is of any importance, any help is really appreciated, as I have been unable to find anything out there.
The standard C input stream stdio is line buffered, and there is no defined way to forcibly flush it. If you want to avoid this and read from the buffer as every new character is entered, you have to use some OS specific magic, which is what _getch from conio.h tries to do.
There are other implementations out there of getch-type functions, for instance getch from the PDCurses library.
Related
I am just playing around with ncurses and so, and I discovered a really weird behaviour.
When i use initscr() from the ncurses lib, and afterwards i use a normal getchar(), then the program terminates after pressing the first key.
The normal getchar() behaviour I would expect, is that i can type (more or less) as long till I press return.
#include "curses.h"
int main()
{
initscr();
getchar();
//endwin();
return 0;
}
Can anyone explain me why this happens?
curses initializes the terminal input to raw mode (which in turn makes the connected stream act as if it is unbuffered), so that curses can detect single-character input. getchar assumes that the input is buffered, so that you would press Enter to end an input line. In raw mode, getchar returns right away, because a read call will find something as soon as you press a key.
Besides endwin, you could use other curses functions for switching back/forth between the terminal's raw/cooked modes (see the manual for reset_shell_mode and reset_prog_mode).
I have developed a simple console utility in C which parses various text files.
IDE - Code Blocks
OS - windows
I intend to distribute its executable.
The executable works fine, however unlike when executed from the IDE, the execution does not pause/wait for keystroke at the end of execution.
I tried using getchar()/system("pause"), but the execution doesn't pause there.
Is there an alternative to wait for keystroke before ending execution, so that the user can view the output?
You can use
getchar();
twice , because its very likely that last '\n' newline character will get consumed by your getchar().
or use
scanf(" %c");
with that extra space
at the end of your file .
It depends on how other parts of your code receives input from the user (i.e. reading from stdin).
The getchar() approach will work fine if your program is not reading anything from the user, or is reading using getchar().
A general guideline, however, is to be consistent in style of input from every stream. Style of input refers to character-oriented (functions like getchar()), line-oriented (like fgets()), formatted (functions like scanf()), or unformatted (like fread()). Each one of those functions does different things depending on input - for example getchar() will read a newline as an integral value, fgets() will leave a newline on the end of the string read if the buffer is long enough, scanf() will often stop when it encounters a newline but leave the newline in the stream to be read next.
The net effect is that different styles of input will interact, and can produce strange effects (e.g. data being ignored, not waiting for input as you are seeing).
For example, if you are using scanf(), you should probably also use scanf() to make your program wait at the end. Not getchar() - because, in practice, there may well be a newline waiting to be read, so getchar() will return immediately, and your program will not pause before terminating.
There are exceptions to the above (e.g. depending on what format string is used, and what the user inputs). But as a rule of thumb: be consistent in the manner you are reading from stdin, and the user will have to work pretty hard to stop your program pausing before terminating.
An easier alternative, of course, is to run the program from the command line (e.g. the CMD.EXE command shell). Then the shell will take over when your program terminates, the program output will be visible to the user, so your program does not need to pause.
Don't use system("pause") since it's not portable. getchar should work on the other hand. Can you post some code? Maybe there's something on the keyboard buffer that's being consumed by your one and only getchar call.
A question about this has been asked here
End of File (EOF) in C
but it still doesn't completely solve my problem.
EOF makes sense to me in any datastream which is not stdin, for example if I have some data.txt file, fgetc() will read all the chars and come to the end of file and return -1.
What I don't understand is the concept of EOF in stdin. If I use getchar(), it will wait for me to enter something, so if there is NOTHING written, End of File, (EOF) is not returned automatically?
So is it that only the user can invoke EOF in stdin by pressing Ctrl+Z?
If so then what are some of the uses of EOF in stdin? I guess it tells the program to continue reading until the user invokes end of file? is this it?
Thank you
so if there is NOTHING written, End of File, (EOF) is not returned automatically?
No, it's not. It should be sent by the user.
So is it that only the user can invoke EOF in stdin by pressing Ctrl+Z?
Yes, you can set the EOF indicator for stdin with a special key combination you can input in the console, for linux console that is Ctrl+D and for windows it's Ctrl+Z.
If so then what are some of the uses of EOF in stdin? I guess it tells the program to continue reading until the user user invokes end of file? is this it?
The use of it depends on whether you instruct the user to input the EOF explicitly or not, for example, I think python console will tell you something like Press Ctrl+D or type quit() to exit.
And EOF is not necessarily -1 it's a macro and you should always use it to test for the EOF indicator. And more importantly EOF is not a character, it's a special value that indicates that the End Of File indicator is set.
Also, getchar() is equivalent to fgetc(stdin).
In linux bash, if you press CTRL+D, it will generate EOF.
In Windows, the equivalent is CTRL+Z
So, no, if nothing written to the terminal, that does not generate EOF automatically. The scanning function is in wait state then. So, without having any other inputs, in wait state, if CTRL+D is pressed, the key press is translated [by the terminal driver] to EOF.Note
Usually, once you key in some value and press the ENTER key, the scannning function starts scanning. To feed an input for producing EOF, you need to press CTRL+D.
Related: Please reaed the wiki entry for EOF
Note: With thanks to Mr Drew for the clarification.
stdin is a stream, data is not available until the user presses some keys. A file on the disk already has (a fixed amount of) content.
When reading from stdin, if getchar() doesn't wait for the user to input something then the program will always get EOF. That will make it impossible to use stdin as an input file.
Because getchar() waits for the user to input something there is no way to signal the input completed; that's why the operating systems provide a combination of keys that have this special meaning when they are pressed on the console.
Windows uses CtrlZ and Unix-like OSes (including OSX) use CtrlD for this purpose.
The file stdin is not always the user typing on the keyboard. If you redirect input to your program, it can be just a normal file.
program.exe <input-from-file.txt
What may be confusing you is that no giving input into a console window does not mark the end of the input. But think it the other way round: how could a user respond so quickly that the program would not terminate before it if the console would not do some buffering for the user? After pressing Enter the user says this is a line of input. In other words: a program running in a console window always waits for the next input to come.
Most programs define a special phrase to end a console session. You probably know exit.
I am using the C code below to read user input from a terminal. If the user inputs EOF, e.g. by pressing ^C, stdin is closed and subsequent attempts to read from it, e.g. via getchar() or scanf(), will cause an exception.
Is there anything I can do in C to "recover" my program, in the sense that if some user accidently inputs EOF, this will be ignored, so I can read from stdin again?
#include <stdio.h>
int main(void)
{
int res_getchar=getchar();
getchar();
return 0;
}
If I understand the situation correctly - you're reading from a terminal via stdin, the user types ^D, you want to discard that and ask again for input - you have two options, one more portable (and quite simple) but less likely to work, and one less portable (and considerably more programming) but certain to work.
The clearerr function is standard C, and is documented to clear both the sticky error and sticky EOF flags on a FILE object; if your problem is that the C library isn't bothering to call read again once it's indicated EOF once, this may help.
If this solves your immediate problem, make sure that if you get some number of EOFs in a row (four to ten, say) you give up and quit, because if stdin is not a terminal, or if the terminal has genuinely been closed down, that EOF condition is never going to go away, and you don't want your program to get stuck in an infinite loop when that happens.
On POSIX-compliant systems only (i.e. "not Windows"), you can use cfmakeraw to disable the input preprocessing that turns ^D into an EOF indication.
Doing this means you also have to handle a whole lot of other stuff yourself; you may instead want to use a third-party library that handles it for you, e.g. readline (GPL) or editline (BSD). If your program is any sort of nontrivial interactive command interpreter, using one of these libraries is strongly encouraged, as it will provide a much nicer user experience.
Using ungetc() to push back a character can clear the EOF indicator for a stream.
C99 ยง7.19.7.11 The ungetc function
int ungetc(int c, FILE *stream);
A successful call to the ungetc function clears the end-of-file indicator for the stream. The value of the file position indicator for the stream after reading or discarding all pushed-back characters shall be the same as it was before the characters were pushed back.
In a word, no. You read EOF when the OS has closed stdin.
I am sure there are Platform-dependent ways to preserve some info that would let you reconstruct stdin after it was closed -- ie, open a new stream connected to the keyboard and assign it to stdin -- but there's definitely no portable way.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C/C++: Capture characters from standard input without waiting for enter to be pressed
I'm using C-Free 4 Standard on windows 7 and I writing a C program.
I'm using getch() as a function to pause the program, however, the character(s) pressed echos on the screen and it waits for the Enter key to be pressed before moving on (it doesn't look any different than how the scanf works). I tried getche(), and it works fine, although the echo appears.
What could be the problem with the getch() function?
The getch, wgetch, mvgetch and mvwgetch, routines read a character
from the window. In no-delay mode, if no input is waiting, the value
ERR is returned. In delay mode, the program waits until the system
passes text through to the program. Depending on the setting of
cbreak, this is after one character (cbreak mode), or after the first
newline (nocbreak mode). In half-delay mode, the program waits until a
character is typed or the specified timeout has been reached.
More or less the same method is used in Windows. You can use _getch() to get the input character available for the application without buffering.
In fact there are several ways to pause the execution of your program until you enter something, one way to do that is by using getchar() (which is part of the function set of stdio.h and an official standard library), It will do the same effect as getch() (this function is part of the functions set of conio.h library which isn't an official library).
If your problem is that you want to avoid pressing Enter every time you enter a character which is not very clear in your question), then read this: How to avoid press enter with any getchar()