Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does getchar() recognize EOF only in the beginning of a line?

Tags:

c

eof

This example is from the K&R book

#include<stdio.h>


main()
{
    long nc;

    nc = 0;
    while(getchar() != EOF)
        ++nc;
    printf("%ld\n", nc);
}

enter image description here

Could you explain me why it works that way. Thanks.

^Z^Z doesn't work either (unless it's in the beginning of a line)

enter image description here

like image 647
Vorgin Avatar asked Jan 21 '13 10:01

Vorgin


People also ask

What is the difference between getchar() and EOF()?

getchar() is a function that reads a character from standard input. EOF is a special character used in C to state that the END OF FILE has been reached. Usually you will get an EOF character returning from getchar() when your standard input is other than console (i.e., a file).

How to get every single character in a file using getchar()?

Then your getchar () will return every single character in somefile and EOF as soon as somefile ends. And send a EOF through the console (by hitting CTRL+D in Unix or CTRL+Z in Windows), then getchar () will also returns EOF and the execution will end. Nice example on polymorphism using getchar (). Reads from the file (input).

How do I get the EOF character from the input string?

Ctrl+Z on Windows, Ctrl+D on *nix. main () { int c; while (1) { c = getchar (); // Get one character from the input if (c == EOF) { break; } // Exit the loop if we receive EOF ("end of file") putchar (c); // Put the character to the output } } The EOF character is received when there is no more input.

What does getchar () return in C?

However, it returns the read characters as an unsigned char in an int, and if there is an error on a file, it returns the EOF at the end of the file. Now we write several getchar () function programs to accept single characters in C and print them using the putchar () function.


1 Answers

Traditional UNIX interpretation of tty EOF character is to make blocking read return after reading whatever is buffered inside a cooked tty line buffer. In the start of a new line, it means read returning 0 (reading zero bytes), and incidentally, 0-sized read is how the end of file condition on ordinary files is detected.

That's why the first EOF in the middle of a line just forces the beginning of the line to be read, not making C runtime library detect an end of file. Two EOF characters in a row produce 0-sized read, because the second one forces an empty buffer to be read by an application.

$ cat
foo[press ^D]foo <=== after ^D, input printed back before EOL, despite cooked mode. No EOF detected
foo[press ^D]foo[press ^D] <=== after first ^D, input printed back, and on second ^D, cat detects EOF

$ cat
Some first line<CR> <=== input
Some first line <=== the line is read and printed
[press ^D] <=== at line start, ^D forces 0-sized read to happen, cat detects EOF

I assume that your C runtime library imitates the semantics described above (there is no special handling of ^Z at the level of kernel32 calls, let alone system calls, on Windows). That's why it would probably detect EOF after ^Z^Z even in the middle of an input line.

like image 195
Anton Kovalenko Avatar answered Oct 12 '22 17:10

Anton Kovalenko