3

I wrote this code :

#include <stdio.h>

int main() {
    int c;

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

    return 0;
}

Under windows, I figured out that I have to input ctrl+z so I can stop the program, I also printed the value of EOF and it's -1. However, when I enter -1 instead of ctrl+z the program continues to execute, and I want to understand why. Thank you!

gsamaras
  • 71,951
  • 46
  • 188
  • 305

4 Answers4

3

Entering "-1" as text does not return the integer value -1 but two characters, i.e. a '-' (which corresponds to ASCII value 45) and a '1' (which corresponds to ASCII value 49). Both do not compare equal to EOF (which is -1 in decimal).

By definition, you cannot enter something that is consumed as negative value by getchar(), as negative values are defined to represent the "End-of-file".

If you want to read in an integral value (like -1), use scanf:

int num;
if (scanf("%d", &num)==1) { // successfully read one valid integral value?
    printf("you entered number %d:", num);
}
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • So how can I enter negative integers? – うちわ 密か Oct 02 '17 at 22:24
  • 4
    @うちわ密か EOF isn't a character, it's a state of the file stream. I happens to be reported to your program as an EOF constant but it's not a character you type. Note that on windows you signal it with ctrl-z but on linux it's ctrl-d. – Blastfurnace Oct 02 '17 at 22:31
  • @Blastfurnace, specifically, when the Windows console is in line-input mode, a line read via `ReadFile` that starts with Ctrl+Z returns that 0 bytes have been read, which libraries and programs interpret as EOF. So on Windows you have to type Ctrl+Z,Enter whereas on Linux it's just Ctrl+D without Enter. This behavior is not implemented for the alternative `ReadConsole` function, but it can actually be used to implement a more Unix-like Ctrl+D instead. At a higher level, the C runtime's standard I/O handles reading Ctrl+Z ("\x1A") as EOF from any text-mode file, not just the console. – Eryk Sun Oct 03 '17 at 04:15
3

The getchar() function returns either the numeric value of the character that was just entered (treated as an unsigned char, so it's never negative), or the special value EOF which indicates that there is no more input.

Windows uses Control-Z to trigger and end-of-file condition, which causes getchar() to return the value EOF. But EOF is not a character value; it's specifically chosen to be a value that cannot be a character value.

End-of-file is a condition, not a value. EOF is a numeric value, but not a character value; it's the value returned by getchar() to indicate that input is in an end-of-file condition (or an error condition).

(If you want to read integer values, positive or negative, you need to read a single character at a time and then compute the integer value that the character sequence represents. The integer value -1 can be entered as the character '-' followed by the character '1'. C has various functions, like atoi and the *scanf family, that can do that conversion.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
2

EOF isn't a 'value'. It is a sentinel defined by the stdio library.

Ctrl/z is a keystroke, that is interpreted by the terminal driver and causes it to notify end of stream to the application reading from it, which causes C read() to return zero, which causes getchar() to return EOF.

The corresponding keystroke on Unix, Linux, etc, is Ctrl/d.

user207421
  • 305,947
  • 44
  • 307
  • 483
-1

You need to change the logic just a bit:

#include <stdio.h>
int main() {
int c;
int done = 0;

while (!done)
{
    c = getchar();
    if(c != '-')
        putchar(c);
    else
    {
        c = getchar();
        if (c == '1')//this is an EOF
        {
            done = 1; // and probably putchar the EOF
        }
        else
        {
              putchar('-');
              putchar(c);
        }
    }//else
}//while
return 0;

}

Paul Gibson
  • 622
  • 1
  • 9
  • 23
  • 1
    Why would you want to do that? Entering `-1` isn't *supposed* to trigger and end-of-file condition. The question was "Why doesn't it do this?", not "How do I make it do this?". – Keith Thompson Oct 02 '17 at 22:55
  • You correctly used the `int` type but `EOF` does not arrive as two separate characters. This is why the return value from `getchar` is `int` not `char`. – Weather Vane Oct 02 '17 at 22:56
  • The question implies that he wants to enter "-1" and have it behave the same way as the ctrl-z. This will let that happen (why the down vote?). The accepted answer is just fine as well, but assumes that only numbers will be input. The question does not describe the kinds of input they are expecting, so I assume it is mostly text characters (rather than numeric). Without that information any of the answers are providing just a guess as to what is desired. – Paul Gibson Oct 03 '17 at 18:09
  • No. The question *states* that he wants to understand *why* -1 doesn't behave the same as ctrl/z. – user207421 Aug 22 '20 at 11:32