2

I'm working through some of the exercises in K&R. Exercise 1-6 asks for verification that the expression getchar() != EOF is either 0 or 1. I understand why it is, but the code I wrote to prove it didn't work as expected. I wrote the following two snippets:

Version 1:

int main(void)
{
    int c;

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

    printf("%d at EOF\n", c);

    return 0;
}

Version 2:

int main(void)
{
    int c;

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

    printf("%d at EOF\n", c);

    return 0;
}

My questions:

  1. When I type in a character and hit enter with version one, why do I not see either a 0 or 1 on the screen? Instead, my cursor moves to the first position on next line, which is otherwise empty. I though putchar would send c to stdout.

  2. While the use of printf in the second version does produce a 0 or 1 appropriately, it duplicates the 1 for each non-EOF character (I see the number 1 on two consecutive lines for each character I input). Why?

Many thanks in advance for your thoughts. If there is a reference that you think would help, please send a link.

CLARIFICATION:

I know I'm assigning c a value of either 0 or 1. That's what I want to do, and it's what the exercise wants. That's also why I don't have parentheses around c = getchar(). My question deals more with understanding why the output isn't what I had expected. Sorry for any confusion.

BruceM
  • 319
  • 1
  • 3
  • 8
  • you should enable warning `-Wall -Wextra` – Stargateur Jul 03 '17 at 21:40
  • I actually compiled the code with gcc. I'm working in an IDE supplied by a course (CS50), and when I tried to compile with make and clang, I couldn't. Wouldn't those warnings just prevent my code from compiling? – BruceM Jul 03 '17 at 21:43
  • "1 for each non-EOF character" --> All characters are non-EOF. End-of_file is a condition, not a character. – chux - Reinstate Monica Jul 03 '17 at 23:06
  • The whole point of adding warning options to the compilation is to prevent **faulty** code from compiling. The compiler knows more about C than you do. The compiler only produces warnings when you tell it to, or when it is convinced that what you've written isn't what you meant to write. I don't run code that doesn't compile with `gcc -Wall -Wextra -Werror -O3 -g -Wstrict-prototypes -Wold-style-declarations -Wold-style-definitions -Wmissing-prototypes` (or as many of these as the local GCC will support). I've better things to do with my time than look for bugs the compiler can spot for me. – Jonathan Leffler Jul 03 '17 at 23:10

1 Answers1

4

The assignment operator = has lower precedence than the inequality operator !=.

So this:

while (c = getchar() != EOF)

Is parsed as:

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

So then c is assigned the boolean value 1 if getchar is not EOF and 0 if it does return EOF.

As a result, the first program print the character for the ASCII code 1, which is a non-printable character. That's why you don't see anything. The second program, using the %d format specifier to printf, converts the number 1 to its string representation.

You need parenthesis to have the result of getchar assigned to c:

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

EDIT:

To further clarify the output you're getting, in both programs the variable c has the value 1 inside of each while loop. The difference here is that putchar is printing the character with the ASCII value of 1 (an unprintable character), while printf with %d print the textual representation of the value 1, i.e. 1.

If you changed the printf call to this:

printf("%c", c);

You would get the same output as using putchar.

As for the printing of 1 twice for each character, that is because you're actually entering two characters: the key you press, plus the enter key. When reading from the console, the getchar function doesn't return until the enter key is pressed.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    You didn't answer the part of the question " it duplicates the 1 for each non-EOF character, why?" (which I guess is due to OP forgetting that he pressed Enter) – M.M Jul 04 '17 at 00:00
  • @dbush, can you also please explain why I see the value 1 twice for each non-EOF character I enter? – BruceM Jul 04 '17 at 02:51
  • 1
    @BruceM See my edit. The extra print is for the newline from the enter key. – dbush Jul 04 '17 at 03:14