Recover stdin from eof in C - c

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.

Related

Is it just best to flush stdout/stderr every single time?

From this stack overflow post: Is stdout line buffered, unbuffered or indeterminate by default?
From that post, it states that "The C99 standard does not specify if the three standard streams are unbuffered or line buffered: It is up to the implementation."
#include <stdio.h>
int main(void) {
printf("Enter name: ");
fflush(stdout);
printf("Another name: ");
fflush(stdout);
return 0;
}
So, does that mean every single time we print, and we want to make sure it is visible to the user, that it's the safest bet to just flush it every single time? Since buffering is up to the implementation?
#include <stdio.h>
int main(void) {
puts("Enter name:");
fflush(stdout);
puts("Another name: ");
fflush(stdout);
return 0;
}
Even on a newline, is it still best to just flush every single time?
I want to 100% make sure the user sees the output, therefore is it best to flush every single time? Even on stderr? Since buffering is up to the implementation?
Looking at the exact examples you show, it's unlikely there will be a visible difference from calling fflush. In particular, you just write two lines of data, and then exit. Normal exit from a program (either by calling exit or returning from main) requires:
Next, all open streams with unwritten buffered data are flushed, all open streams are closed, and all files created by the tmpfile function are removed.
So, the only possibility here would be if the system crashed (or something on that order) immediately after the first fflush call, but before your program exited.
I'd guess, however, that the real intent was when you print out the "Enter name: " prompt, you intended for the program to stop and read a name from the user:
printf("Enter name: ");
char name[256];
fgets(name, sizeof(name), stdin);
For cases like this, flushing the output stream is generally unnecessary.
In particular, the standard says:
When a stream is line buffered, characters are intended to be
transmitted to or from the host environment as a block when a new-line character is
encountered. Furthermore, characters are intended to be transmitted as a block to the host
environment when a buffer is filled, when input is requested on an unbuffered stream, or
when input is requested on a line buffered stream that requires the transmission of
characters from the host environment.
Now, you can make a little bit of an argument that this only talks about what's intended, not what's required. What that basically comes down to is fairly simple: the operating system could do some buffering over which your program has little or no control. So, what it basically comes down to is pretty simple: when you read from stdin, if anything has been written to stdout, but not flushed yet, it'll be flushed automatically before the system waits for input from stdin (unless you've done something like redirecting one or both to a file).
I'm reasonably certain that essentially every argument for doing that flushing explicitly is purely theoretical. In theory, there could be a system that doesn't do it automatically, and that might not quite violate any strict requirement of the standard.
In reality, however, actual systems fall into two categories: those on which the flushing is automatic, so you gain nothing by doing it explicitly, and those on which flushing simply won't do any good, so you gain nothing by doing it explicitly.
Just for an example of the latter, some old terminals for IBM mainframes worked in what you might call a screen-buffered mode. Basically, you'd send a form to the terminal. The user would then edit data into the form. Then when they had filled in the entire form, they pressed a "send" button, and all of the data for the whole form was sent to the CPU at once. On a system like this, calling fflush won't be (nearly) enough to make code work.
Summary
There are systems where calling fflush is unnecessary.
There are systems where calling fflush is insufficient.
I'm reasonably certain there is no system where calling fflush is both necessary and sufficient.
I want to 100% make sure the user sees the output, therefore is it best to flush every single time?
For "100% make sure" best practice is not based on flushing after output, but flushing stdout before input. This is especially true when the output does not end with a '\n'.
It is best to fflush(stdout); when
Right before input from stdin and ...
There has been some output since the prior input from stdin.
Calling fflush(stdout); more often than that does not impact functionality, but may unnecessarily slow code.
There is a 2nd case for fflush(stdout); even without input: Debugging. Sometimes a fatal error occurs with info buffered in stdout. So a fflush(stdout); is warranted prior to the suspected bad code for better analysis.
Even on a newline, is it still best to just flush every single time?
For "100% make sure", the rules for flushing stdout are soft enough to even oblige fflush(stdout); before reading in this case too.
Yet stdout should be unbuffered or line buffered on start-up (see next) and usually not require a flush in this case.
Even on stderr?
C spec has "As initially opened, the standard error stream is not fully
buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device."
As long as the write to stderr ends with a '\n' and buffering mode not changed, then the output should be seen.
Interesting to see how C++ handles end-of-line.
What is the difference between endl and \n in C++?
#paxdiablo nicely answers Why does printf not flush after the call unless a newline is in the format string?
Not really, no. I flush at logical chunks so I can tell more or less where the program crashed and don't have an extra hard debugging time because it crashed with output in the buffer.
The idea is I'm going to call fflush() just before going and doing something else besides produce more output.
Flush too much = slow code.
Calling fflush() right before reading input is harmless (the only question is whether it will do it implicitly or not), so if you're doing that for some reason there's no reason to stop doing it.

How getchar() works when it is used as condition in while loop

I cant understand how the following code really works.
int main() {
char ch;
while((ch=getchar())!='\n')
{
printf("test\n");
}
return 0;
}
Lets say we give as an input "aaa". Then we get the word "test" as an output in 3 seperate lines.
Now my question is, for the first letter that we type, 'a', does the program goes inside the while loop and remembers that it has to print something when the '\n' character is entered? Does it store the characters somewhere and then traverses them and executes the body of the while loop? Im lost.
There are many layers between the user writing input into a terminal, and your program receiving that input.
Typically the terminal itself have a buffer, which is flushed and sent to the operating system when the user presses the Enter key (together with a newline from the Enter key itself).
The operating system will have some internal buffers where the input is stored until the application reads it.
Then in your program the getchar function itself reads from stdin which is usually also buffered, and the characters returned by getchar are taken one by one from that stdin buffer.
And as mentioned in a comment to your question, note that getchar returns an int, which is really important if you ever want to compare what it returns against EOF (which is an int constant).
And you really should compare against EOF, otherwise you won't detect if there's an error or the user presses the "end-of-file" key sequence (Ctrl-D on POSIX systems like Linux or macOS, or Ctrl-Z on Windows).
What you see is due to the I/O line buffering.
The getchar() functions doesn't receive any input until you press the enter. This add the \n completing the line.
Only at this point the OS will start to feed characters to the getchar(), that for each input different from \n prints the test message.
Apparently the printout is done together after you press the enter.
You can change this behavior by modifying the buffering mode with the function setvbuf(). Setting the mode as _IONBF you can force the stream as unbuffered, giving back each character as it is pressed on the keyboard (or at least on an *nix system, MS is not so compliant).

K&R book 1.5.1 File Copying

I have looked around the site regarding this K&R example and the answers seem to revolve around 'why is this a type int or what is EOF?' kinda guys. I believe that I understand those.
It's the results that I don't understand. I had expected this code to take a single character, print it and then wait for another character or EOF.
The results that I see are the input waiting until I press return, then everything that I typed shows up and the more waiting for input.
Is the while loop just 'looping' until I end the text stream with the carrage return and then shows what putchar(c) has been hiding somewhere?
The code is:
#include <stdio.h>
/* copy input to output: 1st version */
main()
{
int c;
c = getchar();
while(c != EOF) {
putchar(c);
c = getchar();
}
}
Now, if I sneak a putchar(c) before on the line just before the while, I sort of get what I expected. I still must enter a text stream and press return. The result is the first character of the stream and the program exits.
Evidently there is a big picture gap for me going on.
Thank you for your help
By default, stdin and stdout are buffered. That means that they save up batches of characters and send them at once for efficiency. Typically, the batch is saved up until there's no more room in the buffer or until there's a newline or EOF in the stream.
When you call getchar(), you're asking from characters from stdin. Supposed you type A, that character is saved in the buffer and then the system waits for more input. If you type B, that character goes into the buffer next. Perhaps after that, you hit Enter, and a newline is put in the buffer. But the newline also interrupts the buffering process, so the original call to getchar() returns the first character in the buffer (A). On the next iteration, you call getchar() again, and it immediately returns the next character in the buffer (B). And so on.
So it's not that your while loop is running until you end the line, it's that the first call to getchar() (when the buffer is empty) is waiting until it has either a full buffer or it has seen a newline.
When you interleave output functions, like putchar(), most C runtime libraries will "flush" stdin when you do something that sends data to stdout (and vice versa). (The intent is to make sure the user sees a prompt before the program waits for input.) That's why you started seeing different behavior when you added the putchar() calls.
You can manually flush a buffer using the flush() function. You can also control the size of the buffer used by the standard streams using setvbuf().
As Han Passant pointed out in the comments, a newline doesn't "terminate the stream." To get an EOF on stdin, you have to type Ctrl+D (or, on some systems, Ctrl+Z). An EOF will also flush the buffer. If you've redirected a file or the output from another program to stdin, the EOF will happen once that input is exhausted.
While it's true that K&R C is very old, and even ANSI C isn't as common today as it was, everything about buffering with stdin and stdout is effectively the same in the current standards and even in C++. I think the only significant change is that the C standards now explicitly call out the desirability of having stdin and stdout cause the other to flush.
I appreciate your answer, and the buffering as you describe is very helpful and interesting.
Evidently, I also must have mis-read/understood, K&R. They define a text stream as ". . . consists of zero or more characters followed by a new line character," which I took to mean the return/enter key; ending it, and then allowing output.
Also, I would like to thank all of you who offered helpful comments.
By the way, I clearly understood that I had to enter ^D to generate EOF, which terminates the program. I appreciate that you are all top level programmers, and thank you for your time. I guess that I will need to find another place to discuss what the text that R&R wrote regarding this exercise is all about.

Pause the execution of exe of a C code

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.

how to read anything after EOF has occured

I was studing the c programming book of k & r. There is this program to count no of characters in input
#include<stdio.h>
main()
{
long nc;
nc=0;
while(getchar()!=EOF)
++nc;
printf("%ld\n",nc);
}
I was wondering how come after EOF has occured nc can be printed. Is there any way to it.
The end-of-file condition only affects stdin, not stdout. Note that there are no uses of stdin after the EOF is found, just printouts to stdout.
I think you're getting two different things mixed up. EOF is with regard to input. printf is an output function.
getchar() reads from stdin. printf() writes to stdout. They are different streams that usually map to the same physical device (console or terminal).
You should not count on a Ctrl-Z or any terminator
If you were counting on that and were running on traditional *nix shells you would suspend your process rather than terminate the input (read up on JOB CONTROL, in man bash, for example)
(I know this answer comes a bit late but I see you keep mentioning Ctrl-Z in you responses to other answers)
If you are on a *nix system you can use Ctrl-D, but dont expect that to end up in your input stream (its just used as a signaling mechanism).m You can also test this with a file input which should give you more consistent results than typing, i.e.
a.out < prog.c
to count the lines in your c program

Resources