2
\$\begingroup\$

Exercise 1-13. Write a program to print a histogram of the lengths of words in its input. It is easy to draw the histogram with the bars horizontal; a vertical orientation is more challenging.

The code I wrote:

#include <stdio.h>
#define MAXWLEN 35 /* assuming no word longer than 35 characters will appear in the input */
#define IN 0
#define OUT 1
int main()
{
 int c, len, longest, state, chart[MAXWLEN];
 for (int i = 0; i < MAXWLEN; ++i)
 chart[i] = 0;
 len = 0; /* length of the current word */
 longest = 0; /* the longest word appearing in the input */
 state = OUT; /* the state of being inside or outside a word */
 while ((c = getchar()) != EOF)
 { 
 if (c == ' ' || c == '\t' || c == '\n')
 {
 if (state == IN)
 if (longest < ++chart[len-1])
 longest = chart[len-1];
 state = OUT;
 len = 0;
 }
 else
 {
 state = IN;
 ++len;
 }
 }
 
 char q[2][3] = {"", " "};
 for (int i = longest; i; --i)
 for (int j = (c = putchar('\n')) - c; j < MAXWLEN; ++j)
 (i <= chart[j]) ? printf(" * ") : printf("%s", q[chart[j] > 0]);
 
 putchar('\n');
 for (int i = 1; i <= MAXWLEN; ++i)
 if(chart[i-1])
 printf("%2d ", i);
 putchar('\n');
 return 0;
}
Toby Speight
87.1k14 gold badges104 silver badges322 bronze badges
asked Aug 21, 2023 at 10:31
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Kernighan didn't ask you to "Write a program which defines several functions", but implicitly you might view it that way. It's always OK to break out helper functions, such as getword(). \$\endgroup\$ Commented Aug 21, 2023 at 16:40

1 Answer 1

5
\$\begingroup\$
  • for (int j = (c = putchar('\n')) - c; is too clever to be good. You save one line of vertical space by the price of a reviewer's mental effort. Don't do this. Be explicit:

     putchar('\n');
     for (int j = 0; ....)
    

    is much more readable.

    Ditto for

     (i <= chart[j]) ? printf(" * ") : printf("%s", q[chart[j] > 0]);
    
  • As said in the comment, more functions please. There are clearly init_chart, fill_chart, and print_chart (every loop deserves to be a function).

    getword is also nice to have. It lets you avoid a IN/OUT state machine.

  • c == ' ' || c == '\t' || c == '\n' is insufficient. At least there is \v (vertical tab) and \f (formfeed). Prefer isspace (don't forget to #include <ctype.h>. (I know that it the K&R times it was not available)

  • putchar may fail. Be prepared.

answered Aug 22, 2023 at 3:14
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.