ceofgetchar

(Exercise 1.6 K&R) How to verfiy that getchar() != EOF IS 0 OR 1?


I have just started to learn programming (C) as a hobby, by myself. I'm using K&R.

 main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}

Verify that getchar() != EOF IS 0 OR 1

I think I understand what is happening:

  1. c is assigned the next character from the keyboard
  2. c is checked whether it is EOF or not
  3. c is assigned 1 or 0, depending if it is EOF or not.
  4. character is shown on output, or if EOF ends the program.

However, my solution is wrong, so clearly I am not understanding something:

main ()
{
    int c;

    while ((c = getchar()) != EOF)
        printf("%d\n", c);
}

This just prints the value of the character. And also prints "10" if I press Carriage Return key.

I thought that it would print c. However, it is printing the character's value rather than the 1 or 0 value.

I know c is assigned 1 or 0 after comparing it with EOF. But I'm not sure what logic I can use to show this. It seems I need to somehow 'get out' of showing the character value, and instead show the comparison value. Does it mean I need to get out of the while loop? If so, I don't know how (and this is just a guess).

How can I simply verify that c = 1 or 0?

And also, how should I know this? There must be something fundamental that I should learn from this, I suppose.

main ()
{
    int c;

    while ((c = getchar()) != EOF != 0 != 1)
        putchar(c);
}

I also did this and I think this seems to work. As it doesn't output any characters, but I'm not sure if this is the solution they are looking for...


Solution

  • I know c is assigned 1 or 0 after comparing it with EOF

    No it isn't. Look:

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

    The expression is: (c = getchar()) != EOF, which contains another expression: (c = getchar()), which assigns to c the character from the keyboard. c will not be equal to 0 or 1! It's the result of the expression. Try this code:

    int main()
    {
       char value;
       int c;
       value = ((c = getchar()) != EOF);
       printf("%i\n", value);
       return 0;
    }
    

    This code will print the value of the expression (c = getchar()) != EOF. Actually, your code could be written like this:

    int main ()
    {
        int c;
        char value = ((c = getchar()) != EOF);
        while (value)
        {
            printf("%d\n", c);
            value = ((c = getchar()) != EOF);
        }
        return 0;
    }
    

    The expression isn't in the while anymore and its result is assigned to value. The code above and your code will produce exactly the same output.


    EDIT:

    main ()
    {
        int c;
    
        while ((c = getchar()) != EOF != 0 != 1)
            putchar(c);
    }
    

    The code above is not the solution! Here is the re-written code:

    main ()
    {
        int c;
        char value1;
        char value2;
        char value3;
    
        value1 = ((c = getchar()) != EOF);
        value2 = value1 != 0;
        value3 = value2 != 1;
        while (value3)
        {
            putchar(c);
            value1 = ((c = getchar()) != EOF);
            value2 = value1 != 0;
            value3 = value2 != 1;
        }
    }
    

    So what happens? Let's say getchar will return the character 'A'. This means that:

    It's important to understand that you can assign to a variable the result of a comparison expression (that means an expression with at least one comparison operator), and the result of this kind of expression is 0 (for false) or 1 (for true).


    Few words about the OP's comment:

    Hey, thanks. But K&R explicitly says "This has the undesired effect of setting c to 1 or 0". Maybe this is why I'm confused.

    c will be assigned to 0 or 1 if the while looks like this:

    while (c = getchar() != EOF)
    

    The operator != has a bigger priority than the operator =. That means that getchar() != EOF will be evaluated first, and then its result will be assigned to c.