18

Does stdin have any EOF? For example, if I start reading from stdin using fread or read, then will the following loop end?

while ((c = read(0, buffer, BUFSIZ)) > 0) { . . . } 

If the answer to this question is no, then is there any way to add EOF to stdin?

6 Answers 6

32

Speaking about EOF in stdin: when you redirect input from file, e.g.:

program <input.txt 

the file already has an EOF, so this is not a problem. In console you can simulate EOF flag. In UNIX systems it is Ctrl+D, in Windows Ctrl+Z. When you type this in the console, program will behave like it has just reached end of input file.


Edit

According to a question asked by OP:

So does it means that stdin don't have EOF and we have to insert them manually using Ctrl+Z or Ctrl+D?

Actually -- yes. One may consider stdin (not redirected, but taken from the console) as infinite file -- no one can tell where does it end. The end of input file, where input ist stdin, must be told literally by Ctrl+D or Ctrl+Z.

Sign up to request clarification or add additional context in comments.

2 Comments

As I've just learned myself, <kbd>Ctrl</kbd>+<kbd>D</kbd> does not 'send EOF' but sends EOT. EOT after not input (or after all input is already sent) makes stdin to have EOF. But when you input "ABC" and then <kbd>Ctrl</kbd>+<kbd>D</kbd> it will just send the buffer to the process and not 'signal' EOF.
If you redirect input from /dev/null it will EOF immediately.
5

I have never programmed C in windows so I can't tell you but in bash, the program will get an EOF when you type end of data (Ctrl+D)

5 Comments

In MS-DOS the Ctrl+Z key will also signal an EOF condition. (But not on *nix systems).
Yes, basically this is sending EOF to the stream
@LukeN Actually it just closes the stream. There is no actual EOF character.
@Bart van Heukelom so after typing Ctrl+D, what should i do if i want to read more inputs from stdin later on? is it possible?
If you're using stdio, you can call clearerr(stdin); to clear the EOF status and you will be able to continue reading. (If stdin is a file that hasn't grown since you got EOF, you'll just get a new EOF condition as soon as you try to read.) If you're using low-level read(), it returns 0 on when the terminal has EOF status, but if you try to read again it will block waiting for input.
2
while ((c = read(0, buffer, BUFSIZ)) > 0) { 

You don't say the type of c but using that name implies that it's a char. Note that the EOF value for iosteams is an (int) -1. Storing that into an unsigned char will get you a value of 255 which will not match EOF.

1 Comment

ok ... c is of int type ... i was just giving the example .... now come back to the original problem and according to you, what is the ans?
0

The way to test for EOF is to check the return value of fread, and then use feof:

while( fread( ... ) ) { // loop so long as fread does not return zero // do something } if ( feof( stdin ) ) { // read failed because of EOF } else { // some other error } 

7 Comments

@Ravi That should not happen.
why? ... you mean to say the while loop will return after a finite number of iterations ... if so the after how many?
@Ravi fread() attempts t read data - if there is nothing to read, it returns zero. So the loop above will read standard input or a file until an EOF is encountered.
@Neil Butterworth ok ... i tried your code and it gives some other errors. So does it means that stdin don't have EOF and we have to insert them manually using Ctrl+Z or Ctrl+D?
It could mean that stdin contained a 0
|
0

Your solution is tagged C++, so here's some C++.

std::string lols; while(!(std::cin >> lols).eof()) { // This loop will end when EOF is reached // Process string } 

3 Comments

will the loop ends? .... that what i am asking ... i am not asking different ways of writing the same code.
You have overcomplicated that and in doing so broken it. If the read fails for some other error then the stream will be marked bad and not read anymore but the EOF will not be reached and thus loop forever. The simpler and correct way to loop would be: 'while( std::cin >> lols) {}'
@Martin York: I did originally have it without the EOF, but the OP's comment shows that he could really use the hint about what's going on. @Ravi Gupta: It will keep going until EOF. That's why I put in the EOF function check. So that it's goddamn obvious that the code executes until EOF. And there's a comment there, telling you that the loop will end when EOF is reached. I mean, this code is pretty self explanatory.
0

First getchar() is really getc(stdin) so getc(FILE) you can read more from that. getchar() gets you last unprocessed character from input stream or stdin pressing enter is '\n'. if the stdin is empty getchar forces a pause to get input. Say in a program I call getchar() at first the stdin is empty so it pauses for input. If I enter ab'\n' the first getchar() will get 97 the ascii of 'a'. the next time i call getchar() i will get b , then again getchar() will have '\n'.

To prove this write this code.

 int choice; do { cout << "Enter input:" ; choice = getchar(); cout << "Last getchar(): " << choice << ":" << (char) choice ; if( choice == '0' || choice == EOF) { cout << "Exited loop" << endl; // EOF is ctrl+z in windows break; } }while(true); 

I do believe stdin is a global so until getchar() or similar function gets called it to clear the stream the characters remain there which can cause bugs later if you use getchar() elsewhere. As people have mentioned you can use gets(char[]) which puts all characters until newline into the character array. The problem with this is you need a char[] larger than input or you will get errors. The nice thing is gets(char[]) does clear stdin so you can make a dumby buffer to clear stdin or process it.

I hope this is informative.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.