3 * Write a program to print a histogram of the lengths of words in its input.
4 * It is easy to draw the histogram with the bars horizontal;
5 * a vertical orientation is more challenging.
9 * NOTE: Word separator tokens are isspace() and EOF.
11 * TODO: Split giant main() into functions?
12 * Make output graph even more flexible
13 * Eliminate all fixed graph output
14 * Support MAX_CHARS > 100
15 * Prove working (unit tests?)
20 #include <ctype.h> /* for isspace() */
22 #define MAX_CHARS 10 /* [< 100] longer words placed in separate column */
23 #define BAR_CHAR '*' /* char used in bars */
24 #define BAR_SEP " " /* spaces between bars */
30 * Occurance freqs of n-character words - words[n].
31 * words[MAX_CHARS+1] is for words > MAX_CHARS.
32 * Init all indices to 0.
34 int words
[MAX_CHARS
+1] = {0};
37 * Read input: Count char num in each word (n); store as words[n-1].
38 * Record last char as lastchar, only needed to check for newline.
40 int lastchar
= EOF
; /* last input char */
41 int chars
= 0; /* chars in each word */
43 while ( (c
= getchar()) ) {
44 if (!isspace(c
) && c
!= EOF
)
47 // End of word/file; bump freq for last word's length.
48 if (chars
<= MAX_CHARS
)
51 ++words
[MAX_CHARS
]; /* long word, last col */
55 chars
= 0; /* prep for next word */
56 lastchar
= c
; /* newlines are isspace() */
60 // Ensure we're on a new line before printing.
61 if (lastchar
!= '\n') {
65 // Longest bar needs first print; find it.
67 for (int bar
= 1; bar
<= MAX_CHARS
; ++bar
)
68 if (words
[longest_bar
] < words
[bar
])
74 for (int y
= words
[longest_bar
]; y
> 0; --y
) {
79 for (int bar
= 0; bar
< MAX_CHARS
; ++bar
) {
84 printf(BAR_SEP
); /* bar separator */
87 putchar('\n'); /* avoid extra spaces */
90 // Print bottom border.
92 for (int bar
= 0; bar
< MAX_CHARS
; ++bar
)
94 printf("--\n"); /* avoid extra spaces */
98 for (int bar
= 0; bar
< MAX_CHARS
; ++bar
)
99 printf("%2d ", bar
+1);
101 // Avoid extra spaces, and use '>' for last bar.
102 printf(">%d\n", MAX_CHARS
);