tags:

views:

89

answers:

2

The title pretty much says it all, so here's the code:

#include <stdio.h>

/* Program counts blanks, tabs, and newlines */
int main(void)
{
  int c;
  int b, t, nl;

  b = 0;
  t = 0;
  nl = 0;

  while ((c = getchar()) != EOF)
    if (c == ' ')
      ++b;
    if (c == '\t')
      ++t;
    if (c == '\n')
      ++nl;
  printf("Input has %d blanks, %d tabs, and %d newlines\n", b, t, nl);
  return 0;
}

I don't understand why this doesn't work. It counts the blanks no problem, but then when it comes to the rest their values always get printed as 0.

More than a "here's how it should be" answer, I'd really like a "it doesn't work because... you need to do this because..." answer please. I'm trying to grasp the concepts and actually understand the language more than just know what works and what doesn't.

Thanks! You guys have been already helped tons :).

+10  A: 

It's because you're missing braces for your while loop. Without those braces, the only thing inside the while is the first if statement. That's why it's only counting blanks, because you go through the whole file doing that one if statement then, after exiting the loop, c is EOF so neither of the other two if statements will be true.

That was a tricky one, it's hard to see because the indentation looks like it should work but, unlike Python, the compiler doesn't use indentation to figure out where things are :-)

If you put a opening brace after the while and a closing brace before the printf, it should count everything.

In other words, this is what your compiler sees:

while ((c = getchar()) != EOF) {
    if (c == ' ')
        ++b;
}
if (c == '\t')
    ++t;
if (c == '\n')
    ++nl;

whereas you want:

while ((c = getchar()) != EOF) {
    if (c == ' ')
        ++b;
    if (c == '\t')
        ++t;
    if (c == '\n')
        ++nl;
}
paxdiablo
it pays to brace whiles and ifs always, especially when first learning
Keith Nicholas
Michael Aaron Safyan
Uh, I didn't even notice... +1 to you
Robus
Our coding standard requires braces always.
progrmr
Awesome answer, thanks! It all makes complete sense now.And yeah K-).
MW2000
Yes, even if you have the one with the black banner on the cover stating "Based on draft-proposed ANSI C standard", it's a bit long in the tooth (that was somewhere around 1990, twenty years ago). If you have the _first_ edition, either keep it as a historical item or burn it. Don't use it for learning C :-)
paxdiablo
@pax, the [latest version](http://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628) (with a red stamp) of the 2nd edition is based on the approved C89 standard.
Matthew Flaschen
Oh well, that's alright then. It's not as if we've had another standard since then and yet another just around the corner :-) Though I'm curious how the publishers got to release _two_ second editions. I can only assume there were no substantive changes between the almost-ANSI and ANSI iterations.
paxdiablo
@pax, I'd like to see a version for C99 (and C1X!). But even a little behind, the second edition is a great resource. I imagine they made small changes to both the content and cover when the final standard arrived.
Matthew Flaschen
+1 Great observation.
Praveen S
I have the second edition (the second, second...)... the one with a red stamp.
MW2000
If you used `else if` instead of `if`, you wouldn't need the braces. :-)
R..
A: 

I see a lot of "always require braces" here. That's fine, and it will prevent this from happening, but I tend to prefer to always use a good editor. Emacs, for example, will automatically indent C code to make this sort of thing very obvious. Your 2nd and third if statements wouldn't indent as far as they are.

Another alternative, if you dislike braces, is to use else if where you use if. Don't do that, but do understand it.

Nathon