Re: K&R2 ex 1-8

From: Merrill & Michele (beckjensen_at_comcast.net)
Date: 10/15/04


Date: Fri, 15 Oct 2004 15:47:47 -0500


> > The following is my best attempt to solve the exercise in the subject
line
> > whose simple request is to write a program that counts blanks, tabs and
> > newlines.
> >
> > #include <stdio.h>
> > int main(int orange, char **apple)
> > {
> > int c,n1,n2,n3;
> > n1=n2=n3=0;
> > while((c=getchar()) != EOF)
> > {
> > if (c=='\n')
> > ++n1;
> > else if (c=='\t')
> > ++n2;
> > else if (c==' ')
> > ++n3;
> > }
> > printf("%d %d %d\n",n1,n2,n3);
> > return (0);
> > }
> >
> > This compiles, links and behaves on my windows platform except for the
> > newline character. If your response to me is that I'm an idiot, you are
> > probably correct, but I would prefer that you show such condition in
light
> > of this code. ++Thanks. MPJ

> "Keith Thompson" <kst-u@mib.org>
> I don't see any real problem with your program. I do have some
> stylistic quibbles; I'll get to that later.
>
> I compiled and ran the program myself, and it seems to work correctly.
> Examining the code, I don't see any reason why it shouldn't. I
> applaud you for showing us a complete compilable program that exhibits
> the problem; far too many posters fail to do so, leaving us to guess
> what the actual program looks like.
>
> Unfortunately, you've left us to guess what the problem is. You say
> that it behaves "except for the newline character". What exactly do
> you mean by that? For a given input, what output are you actually
> getting, and what output did you expect? (If I had to guess, I'd say
> that the program is behaving correctly, and your expectation is
> incorrect.)
>
> As for style concerns, your indentation is too narrow and is not
> consistent, and it's best to use more blanks (after commas and around
> most operators). Here's a modified version of your program, changing
> only indentation and spacing:
>
> #include <stdio.h>
> int main(int orange, char **apple)
> {
> int c, n1, n2, n3;
> n1 = n2 = n3 = 0;
> while ((c=getchar()) != EOF)
> {
> if (c == '\n')
> ++n1;
> else if (c == '\t')
> ++n2;
> else if (c == ' ')
> ++n3;
> }
> printf("%d %d %d\n", n1, n2, n3);
> return (0);
> }
>
> I didn't add spacing around the "=" in "c=getchar()" so as to
> emphasize the grouping.
>
> Your use of "orange" and "apple" as the names of the arguments to main
> is perfectly legal. It's also useless and annoying. The universal
> convention is to use the names "argc" and "argv". By changing these
> to "orange" and "apple", you make your code more difficult to read,
> with no benefit whatsoever. For that matter, you don't use the
> arguments, so you might as well use "int main(void)".
>
> The parentheses around the argument to return are perfectly legal, but
> unnecessary and potentially misleading. A return statement is not a
> function call; your code is clearer if you don't make it look like
> one. This isn't a big deal though; nobody reading your code is likely
> to be confused.
>
> I usually avoid declaring more than one variable on a line. If I'm
> going to assign a value to the variable, I'd rather do it as an
> initialization rather than as a separate assignment statement; it's
> clearer and less error-prone.
>
> If an "if" or other control statement controls only a single
> statement, it doesn't have to be surrounded by curly braces. Strictly
> speaking, since the "if ... else if ... else if" is a single
> statement, the braces associated with the "while" are unnecessary.
> Nevertheless, it's a very good idea to include them anyway. In fact,
> I would go even farther; I *always* use braces in control statements,
> even if they surround just a single simple statement (unless I put the
> whole thing on one line, but that's rare). It gives the code a more
> consistent look, and it avoids errors when I want to add another
> statement. I suspect most C programmers would disagree with me on
> this point. (It's a habit I picked up from Perl, which requires the
> braces.)
>
> (If I felt like being overly terse, I might write:
>
> if (c == '\n') ++n1;
> else if (c == '\t') ++n2;
> else if (c == ' ') ++n3;
>
> but that makes adding more statements even more difficult.)
>
> The names n1, n2, and n3 are extremely unclear. It's not that
> important for a tiny program like this, but for larger programs it
> becomse extremely important to pick meaningful variable names.
>
> Here's another version of your program, incorporating these points
> (and using the brace style that I happen to prefer):
>
> #include <stdio.h>
> int main(void)
> {
> int c;
> int newlines = 0;
> int tabs = 0;
> int blanks = 0;
>
> while ((c=getchar()) != EOF) {
> if (c == '\n') {
> newlines ++;
> }
> else if (c == '\t') {
> tabs ++;
> }
> else if (c == ' ') {
> blanks ++;
> }
> }
> printf("%d %d %d\n", newlines, tabs, blanks);
> return 0;
> }
>
> Finally, I'd probably use a switch statement rather than a chain of if
> statements.

Thank you for your attention. The stylistic stuff I have to see as a hard
copy, but I wanted to get at the crux of what's not working for me. I
invoke the executable and am presented with a window. In order for any
keystroke to processed, I must hit 'enter.' Thus, I can hit tab enter tab
enter space enter, and my output is 0 enters 2 tabs 1 space. When I hit
enter enter enter enter, I get three zeroes. I swear I remember Heathfield
saying something about getchar.

That I need to wait to read something that comes off the net on ink and
paper in my study is as high a compliment as I give. MPJ



Relevant Pages