Question

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

Was it helpful?

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:

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

OTHER TIPS

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);

'c' is assigned the value from getchar and then checked for whether or not it is EOF.

If it is not assigned EOF, print the value of 'c'; if not, exist the loop.

the test for EOF does not reassign any value to 'c', it only succeeds or fails

IOW, remove your step 3.

Here c is not assigned to the result of comparison.It contains the value read form File.

To check the result of comparison you need as follows

int result = ((c = getchar()) != EOF)

Then use the result to check it is 0 or 1.

printf("%d",result);

I was having tons of trouble with this very problem.

And also prints "10" if I press Carriage Return key.

Also, page 20 K&R states that the ASCII value for '\n' is 10. So perhaps you are returning that value unintentionally?

Everytime I come back to it, I forget that Carriage Return key IS NOT EOF.

Like user Sayyora points out above, you need a key combo to signal EOF.

For Linux it is:

Ctrl + D

Also, to kill program (in X-Term at least), it is:

Ctrl + C

I'm using a C source file within DevC++ 4.9.9.2. I'm new to programming in C and I'm using K/R 2nd Ed. as my guide. After reviewing statements from above, I found the following lines provided me the output desired by Example 1.6/1.7. Feel free to correct my understanding, but by picking up on the author(s) tip about use of parenthesis and printing both inside and outside the while loop, one is able to obtain a result of 1 or 0. The last getchar() is a requirement of the Dev-C environment to hold the input/output screen open for review of printed statements.

main()
{
      int c; 
      while (c=getchar() !=EOF)
            printf("%d",c);
      printf("%d",c);
      getchar();      
// it will accept and print a single char, a word, a sentence...

while (c != EOF) {
  printf("\ngetchar()) != EOF) = %d -- ", ((c=getchar()) != EOF));
  putchar(c);
}

//the trick is to only call getchar() once per char and EOF value
//note: the last char is always char(10) which is invisible
#include <stdio.h>
   
int main(){
    int c;
    printf("Verifying that the expression 'c = getchar() != EOF' is: %d \n", (getchar() != EOF));
   
    return 0;
}

Well when you enter value to the 'c' it is != so it return '1' and when you send EOF command it returns '0'.

In my opinion this is the exercise from the book since it is in the beginning it shouldn't be more complicated.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top