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

BBedit picture BBedit · Jul 19, 2013 · Viewed 11.4k times · Source

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...

Answer

nouney picture nouney · Jul 19, 2013

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:

  • value1 will be equal to 1, since 'A' is different than EOF.
  • value2 will be equal to 1, because value1 (which is equal to 1) is different than 0.
  • value3 will be equal to 0, because value2 (which is equal to 1) is not different than 1: while(value3) is now while(0), so no characters will be printed.

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.