51

How do you get to see the last print? In other words what to put in for EOF? I checked the definitions and it says EOF is -1.

And if you enter Ctrl-D you won't see anything.

#include <stdio.h>

int main() {
 int c;
 while((c = getchar() != EOF)) {
  printf("%d\n", c);
 }
 printf("%d - at EOF\n", c);
}
6
  • Do you mind to clarify? What is your question?
    – qrdl
    Commented Nov 23, 2009 at 9:41
  • I want to put in EOF and get to see printf("%d - at EOF\n", c);
    – Chris_45
    Commented Nov 23, 2009 at 9:45
  • and EOF is said to be -1 but it interprets that as three characters and puts out three 1's
    – Chris_45
    Commented Nov 23, 2009 at 9:46
  • 3
    @reinierpost: EOF in C is a macro defined in stdio.h.
    – Lucas
    Commented Nov 23, 2009 at 10:27
  • 6
    I found this very useful: latedev.wordpress.com/2012/12/04/all-about-eof Commented Jan 13, 2015 at 16:44

10 Answers 10

58

On Linux systems and OS X, the character to input to cause an EOF is Ctrl-D. For Windows, it's Ctrl-Z.

Depending on the operating system, this character will only work if it's the first character on a line, i.e. the first character after an Enter. Since console input is often line-oriented, the system may also not recognize the EOF character until after you've followed it up with an Enter.

And yes, if that character is recognized as an EOF, then your program will never see the actual character. Instead, a C program will get a -1 from getchar().

9
  • Ok but what's the difference between Ctrl-z and Ctrl-D on Windows? Ctrl-z = EFO Ctrl-D = kill?
    – Chris_45
    Commented Nov 23, 2009 at 10:14
  • @Chris_45: On Windows, Ctrl-Z marks EOF, Ctrl-D is just Ctrl-D (or character 04). @gotch4: It's standard (but little used) HTML: < kbd >. Commented Nov 23, 2009 at 11:50
  • 1
    @Chris_45: Ctrl-D corresponds to ASCII EOT (end-of-transmission), MS-DOS however used Ctrl-Z (ASCII SUB) for compatibility with CP/M, and Windows inherits that. In CP/M the EOF character was actually a character in the file, because all files had to be multiples of 128 characters. The character used to signal EOF is specific to the OS not the programming language. en.wikipedia.org/wiki/End-of-file
    – Clifford
    Commented Nov 23, 2009 at 14:15
  • Well I meant the difference between Ctrl-Z and Ctrl-C? not Ctrl-d
    – Chris_45
    Commented Nov 23, 2009 at 14:34
  • 5
    Then say so! :) Ctrl-C will usually kill a program that's accepting input from the console. Ctrl-D will mark the end of input but the program could continue running after that. Commented Nov 23, 2009 at 19:07
32

You should change your parenthesis to

while((c = getchar()) != EOF)

Because the "=" operator has a lower precedence than the "!=" operator. Then you will get the expected results. Your expression is equal to

while (c = (getchar()!= EOF))

You are getting the two 1's as output, because you are making the comparison "c!=EOF". This will always become one for the character you entered and then the "\n" that follows by hitting return. Except for the last comparison where c really is EOF it will give you a 0.

EDIT about EOF: EOF is typically -1, but this is not guaranteed by the standard. The standard only defines about EOF in section 7.19.1:

EOF which expands to an integer constant expression, with type int and a negative value, that is returned by several functions to indicate end-of-file, that is, no more input from a stream;

It is reasonable to assume that EOF equals -1, but when using EOF you should not test against the specific value, but rather use the macro.

4
  • "EOF which expands to an integer constant expression, with type int and a negative value" Int is 32 bits and EOF signals success typically on the wchar_t value of -1 (or 65535) or the char value -1 with an extraneous ÿ. Commented Jan 23, 2016 at 4:25
  • @LaurieStearn: In C, EOF is really just a macro that expands to a constant integer expression (typically defined in some header as something like: #define EOF (-1)) and is therefore typically 4 bytes wide. The EOF macro doesn't signal anything, since it is just a value. getchar - as defined in the standard library - always returns an integer value and when it returns a value equivalent to EOF (typically -1) indicates that it has reached the end of the file. The underlying mechanism is obviously dependent on your C-runtime and you can't really make any generalizing statements.
    – Lucas
    Commented Jan 23, 2016 at 13:30
  • @Lucas: Forgive my necro rant, Agreed. In VS10, the 65535 isn't strictly an int, but there's something going on with the 2's complement and the sign bit to make it so it seems. Commented Jan 23, 2016 at 13:54
  • Gah, Didn't know there was a wide version of EOF, as explained here. Commented Jan 24, 2016 at 6:50
11

The value of EOF is a negative integer to distinguish it from "char" values that are in the range 0 to 255. It is typically -1, but it could be any other negative number ... according to the POSIX specs, so you should not assume it is -1.

The ^D character is what you type at a console stream on UNIX/Linux to tell it to logically end an input stream. But in other contexts (like when you are reading from a file) it is just another data character. Either way, the ^D character (meaning end of input) never makes it to application code.

As @Bastien says, EOF is also returned if getchar() fails. Strictly speaking, you should call ferror or feof to see whether the EOF represents an error or an end of stream. But in most cases your application will do the same thing in either case.

2
  • So you can never make the EOF on win32 make it to the appcode and see the last print?
    – Chris_45
    Commented Nov 23, 2009 at 9:53
  • @Chris_45 - I'm talking about the meaning of EOF. The root cause of the bug in your "appcode" is something completely different -- see @Lucas's answer,
    – Stephen C
    Commented Nov 23, 2009 at 21:33
4

EOF means end of file. It's a sign that the end of a file is reached, and that there will be no data anymore.

Edit:

I stand corrected. In this case it's not an end of file. As mentioned, it is passed when CTRL+d (linux) or CTRL+z (windows) is passed.

3
  • The edit is incorrect. The phrase "it is passed when CTRL+d...is [pressed]" is nonsense. When the user types ctrl-D, the input file is closed and getchar returns EOF to indicate that the end of file has been reached. There is no EOF character that is sent to the process. Commented Jan 9, 2013 at 22:47
  • What do you mean it is a sign? Is it a specific bit pattern? Commented Jan 11, 2015 at 12:09
  • He means sign in the normal (non-IT, non-mathematical) sense; i.e. an indication. At dog wags its tail as a sign that it is happy.
    – Stephen C
    Commented Apr 16, 2020 at 6:03
4

Couple of typos:

while((c = getchar())!= EOF)

in place of:

while((c = getchar() != EOF))

Also getchar() treats a return key as a valid input, so you need to buffer it too.EOF is a marker to indicate end of input. Generally it is an int with all bits set.


#include <stdio.h>
int main()
{
 int c;
 while((c = getchar())!= EOF)
 {
  if( getchar() == EOF )
    break;
  printf(" %d\n", c);
 }
  printf("%d %u %x- at EOF\n", c , c, c);
}

prints:

49
50
-1 4294967295 ffffffff- at EOF

for input:

1
2
<ctrl-d>
3
  • 2
    Isn't there a bug in your code as well? You call getchar() twice (once in the while loop and once in the if), so very second input will be lost...
    – Heinzi
    Commented Nov 23, 2009 at 10:48
  • It works because the second getchar() gets the '\n' from hitting return.
    – Lucas
    Commented Nov 23, 2009 at 11:11
  • @Heinzi the second getchar() is used to capture the "\n" from return. This was done to explain the behavior OP got in hi code..
    – sud03r
    Commented Nov 23, 2009 at 11:44
3

nput from a terminal never really "ends" (unless the device is disconnected), but it is useful to enter more than one "file" into a terminal, so a key sequence is reserved to indicate end of input. In UNIX the translation of the keystroke to EOF is performed by the terminal driver, so a program does not need to distinguish terminals from other input files. By default, the driver converts a Control-D character at the start of a line into an end-of-file indicator. To insert an actual Control-D (ASCII 04) character into the input stream, the user precedes it with a "quote" command character (usually Control-V). AmigaDOS is similar but uses Control-\ instead of Control-D.

In Microsoft's DOS and Windows (and in CP/M and many DEC operating systems), reading from the terminal will never produce an EOF. Instead, programs recognize that the source is a terminal (or other "character device") and interpret a given reserved character or sequence as an end-of-file indicator; most commonly this is an ASCII Control-Z, code 26. Some MS-DOS programs, including parts of the Microsoft MS-DOS shell (COMMAND.COM) and operating-system utility programs (such as EDLIN), treat a Control-Z in a text file as marking the end of meaningful data, and/or append a Control-Z to the end when writing a text file. This was done for two reasons:

  1. Backward compatibility with CP/M. The CP/M file system only recorded the lengths of files in multiples of 128-byte "records", so by convention a Control-Z character was used to mark the end of meaningful data if it ended in the middle of a record. The MS-DOS filesystem has always recorded the exact byte-length of files, so this was never necessary on MS-DOS.

  2. It allows programs to use the same code to read input from both a terminal and a text file.

1
#include <stdio.h>

int main() {
    int c;
    while((c = getchar()) != EOF) { //precedence of != is greater than =, so use braces
        printf("%d\n", c);
    }
    printf("%d - at EOF\n", c);
}

I think this is right way to check value of EOF. And I checked the output.

For INPUT: abc and Enter I got OUTPUT: 97 98 99 10. ( the ASCII values)

For INPUT Ctrl-D I got OUTPUT: -1 - at EOF. So I think -1 is the value for EOF.

Try other inputs instead of Ctrl-D, like Ctrl-Z. I think it varies from compiler to compiler.

1
  • 1
    Sure, stdio.h defines EOF as -1. But that shouldn't interest you, nor do you need to look at it or print it out. Just check for EOF in your code and let the compiler worry about the details. Commented Nov 23, 2009 at 11:57
0

to keep it simple: EOF is an integer type with value -1. Therefore, we must use an integer variable to test EOF.

-1
#include <stdio.h>

int main() {
    int c;
    while((c = getchar()) != EOF) { 
        putchar(c);
    }    
    printf("%d  at EOF\n", c);
}

modified the above code to give more clarity on EOF, Press Ctrl+d and putchar is used to print the char avoid using printf within while loop.

1
  • tested on ubuntu 14.04 Commented Jun 7, 2016 at 6:08
-3
int c;

while((c = getchar())!= 10)
{
    if( getchar() == EOF )
        break;

     printf(" %d\n", c);
}
1
  • 1
    Not sure what the purpose of this answer is (or why some people dump blocks of code on SO with no explanation), but note the bug here: every second character is discarded due to the faulty EOF checking logic. Commented Sep 8, 2020 at 7:39

Not the answer you're looking for? Browse other questions tagged or ask your own question.