Answer Book鼓励使用标准库提供的字符分类功能,以便从控制字符和空格中识别可打印字符。
使用它们不仅可以将不同类型的字符放入定义明确的组中,而且在这个特定练习的情况下,可以用于最终报告的详细表示。
例如,在阅读循环中,函数可以将可打印字符的总数计算为
isprint
int printable = 0;
while ( (c = getchar()) != EOF )
if ( isprint(c) )
++printable;
同时阻止程序员制定类似的东西
if (c >= ' ' && c <= '~')
事实上,可能性是无限的。以下是 The Answer Book 解决方案的修改版本。
#include <stdio.h>
#include <ctype.h>
#define MAXHIST 15 /* max length of histogram */
#define MAXCHAR 128 /* max different characters */
int main()
{
int c,
i,
len, /* length of each bar */
maxvalue, /* maximum value of cc[] */
cc[MAXCHAR], /* char frequency counters */
totalc, /* total chars of input */
whitec, /* whitespaces chars */
digitc, /* numeric chars */
upperc, /* uppercase chars */
lowerc, /* lowercase chars */
punctc; /* punctuation marks */
totalc = whitec = digitc =
upperc = lowerc = punctc = 0;
for (int i = 0; i < MAXCHAR; ++i)
cc[i] = 0;
while ((c = getchar()) != EOF)
if(c >= 0 && c < MAXCHAR) {
++cc[c];
++totalc;
if (isspace(c)) ++whitec;
else if (isdigit(c)) ++digitc;
else if (isalpha(c)) {
if (isupper(c)) ++upperc;
else ++lowerc;
}
else if (ispunct(c)) ++punctc;
}
maxvalue = 0;
for (i = 0; i < MAXCHAR; ++i)
if (cc[i] > maxvalue)
maxvalue = cc[i];
printf("\n%s - %s - %s\n", "ASCII", "CH", "Freq");
printf("~~~~~~~~~~~~~~~~~~~~\n");
for (i = 0; i < MAXCHAR; ++i) {
if (cc[i] == 0)
continue;
if (isprint(i))
printf("%5d - %2c - %5d : ", i, i, cc[i]);
else
printf("%5d - - %5d : ", i, cc[i]);
if (cc[i] > 0) {
if ((len = cc[i] * MAXHIST / maxvalue) <= 0)
len = 1;
} else
len = 0;
while (len > 0) {
putchar('*');
--len;
}
putchar('\n');
}
printf("\n*** Detailed report ***\n");
printf("Total # of chars : %4d\n"
"Total # of whitespaces: %4d\n"
"Total # of numbers : %4d\n"
"Total # of letters : %4d (%4d upper + %4d lower)\n"
"Total # of puncts : %4d",
totalc, whitec, digitc,
upperc + lowerc, upperc, lowerc,
punctc);
}
样本输入 (OP的第一段)
所以我想做的是制作 a、b、c、d 和其他频率的直方图。我想知道为什么当我给程序输入说“abcde”时,当“e”只出现一次时,“其他”被计算多次。
样本输出
ASCII - CH - Freq
~~~~~~~~~~~~~~~~~~~~
32 - - 43 : ***************
34 - " - 2 : *
39 - ' - 5 : *
44 - , - 4 : *
46 - . - 2 : *
73 - I - 3 : *
97 - a - 12 : ****
98 - b - 2 : *
99 - c - 7 : **
100 - d - 6 : **
101 - e - 18 : ******
102 - f - 4 : *
103 - g - 5 : *
104 - h - 10 : ***
105 - i - 8 : **
107 - k - 1 : *
108 - l - 1 : *
109 - m - 6 : **
110 - n - 14 : ****
111 - o - 18 : ******
112 - p - 2 : *
113 - q - 1 : *
114 - r - 10 : ***
115 - s - 8 : **
116 - t - 13 : ****
117 - u - 4 : *
118 - v - 1 : *
119 - w - 6 : **
121 - y - 5 : *
*** Detailed report ***
Total # of chars : 221
Total # of whitespaces: 43
Total # of numbers : 0
Total # of letters : 165 ( 3 upper + 162 lower)
Total # of puncts : 13