Print line by character in C

Hello, I am reading the K & R C book, and trying to understand more about putchar()/getchar() by practice. Similar to the exercise 1-12, I want try to parse each line by character. Although there are many site about the exercise, but I could find similar case of mine, which is similar to fold command. Not sure it's my code problem, or from my display setting.

#include <stdio.h>
/*count the characters in input; */

main() {
  char c;

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

}

Input:

A test

And I am expecting output like:

A

t
e
s
t

But I got strange char on the screen, can't be pasted here. What did I miss? Thanks!

printf("%c\n", putchar(c));
// should be
printf("%c\n", c);

I think your while condition is also slightly wrong.

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

No, still not working. There is no error at compiling, and running of the compiled program seems working too, except the char are not corrected printed out. E.g:

$ ./print_by_char
A test
[ ]
[ ]
[ ]
[ ]
[ ]
[ ]
$ 

Those [ ] on my screen are tiny squares with 0001 inside like.

|00|
|01|

I thought it may be related to display or language setting that I have no idea about, but testing of some other code from the book were fine. I am using Ubuntu 12.10 with bash. $LANG=en_CA.UTF-8.
Scott, it seem the syntax is correct.
Any other clue? Thanks!

It's probably some typo you are making. Try again with code below. If it does not work, post what you are seeing.

$ cat test.c
#include <stdio.h>

main() {
  int c;

  while ((c = getchar()) != EOF) {
    printf("%c\n", c);
    }
  }
$ cat input
A test
$ gcc test.c
$ a.out < input
A

t
e
s
t
[ blank line ]
[ blank line ]
1 Like

The O's and 1's are the false's and true's that getchar() != EOF is returning into c because your condition is wrong.

$ cat main.c
#include <stdio.h>
/*count the characters in input; */

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

  return 0;
}
$ cc -o main main.c
$ ./main           
Hello World
H
e
l
l
o
 
W
o
r
l
d
1 Like

Scott is right!
The only difference is the order of the condition. Mine is

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

and yours, both of you, are

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

Now I got it. But, with my condition, it should print out seven "1", but why it printed out 7 unprintable chars (I use x here!) like this?

A Test
x
x
x
x
x
x
x

That's the very subtle but most important part I have missed.
Thanks again, to both of you!

That's a GREAT question!. :smiley:

Remember that the "c" variable is an int variable. You are using it to store what we call a "character", but ultimately "c" just holds a number.

What number does it store?

Under the "good" logic, it stores ASCII decimal 65 for 'A', etc. for each character it reads. That is fine.

Under the "bad" logic, it stores a 0 or 1 (equal or unequal). What ASCII characters do 0 or 1 represent? Some weird control character. That's why you get the garbage printed.

Does that make sense to you?

1 Like

Very much! You also answered my question why int is used for getch() and putch() functions in K&R C_book.

How hard was that bug to see?

That's why it's a bad idea to perform assignments inside the conditional clause of thing like an if statement or while loop.

So what if it saves a line or two of code. Writing quality code is not a contest to see who can stuff the most operations in the least number of lines. Especially given that you wind up with bug-prone and hard-to-understand code.

Agreed! I'm trying to pick up C by myself, not for contest or homework. Thank unix.com, I do not need to go back to school, maybe I'd better do it.

I wouldn't worry about it too much. You're doing fine, it just takes a while when you are learning.

I agree with achenlee that there is too much obscure C code, with stuff jammed on one line. I don't write that way. But you see it a lot. Even K&R frequently emphasizes that style. Many expert programmers are used to that kind of terse code, and seem to like it. So you have to also learn to understand it.