Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c

eof

getchar

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

like image 686
BBedit Avatar asked Jul 19 '13 12:07

BBedit


2 Answers

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.

like image 199
nouney Avatar answered Sep 20 '22 10:09

nouney


I realize the question is old but the selected answer is answering something that is not what the question is intended to be asked. (It is a different question asked from the book) I am here to clarify a few things and hope that other people who searched this question up from Google can read my answer for a better understanding of question 1-6 from The C Programming Language 2nd Edition.

The question stated verify that getchar() != EOF IS 0 OR 1

The book hinted that

**c = (getchar() != EOF)**

is equivalent to

**c = getchar() != EOF**

When getchar() != EOF is tested,

If the input is not EOF, then it should be true, hence returning a True, or a 1 in this sense.

And of course, if input is EOF, then getchar() != EOF will return a False, or a 0.

That is why either 1 or 0 will be assigned into c.

For the "undesirable effect" mentioned in the book, because neither 1 nor 0 is the original input, this means that the original character intended to be output is lost, and this is undesirable.

For the exercise, use this:

#include <stdio.h>

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

If your input is not EOF, then it will print 1.

If your input is EOF, then the program ends.

NOTE: To type EOF in Windows, use Ctrl + Z

Edit:

A simpler solution to Exercise 1.6 of K&R.

printf("%d", getchar() != EOF);
like image 44
Sayyora Avatar answered Sep 17 '22 10:09

Sayyora