我正试图从Brian Kernighan的C编程语言书中练习1-14。
我正在使用一个列表,其中索引号对应于ASCII值,因此列表[65]应该打印出“A”出现在输入中的次数。
不幸的是我的程序似乎没有增加。任何帮助将不胜感激!
#include <stdio.h>
#define MAXLEN 1000
int main()
{
int c, i;
int chartype[MAXLEN];
for(i = 0; i < MAXLEN; ++i)
chartype[i] = 0;
while((c = getchar()) != EOF){
++chartype[c - '0'];
}
for(i = 0; i < MAXLEN; ++i){
if(chartype[i]>0)
printf("%c, %d\n", i, chartype[i]);
}
return 0;
}
输出:53,? 56,?
答案 0 :(得分:3)
这里的问题是第二个循环中的c - '0'
。
当你输入'A'时,你正在递增索引位置c - '0'的整数,即c - 48.所以对于'A',它是递增整数17(65-48),这是一些特殊的角色。
只需输入++chartype[c]
,即可增加数组中字符的位置并解决问题。
当您在输入控制台上按Enter键或遇到输入文件中的行尾时,getchar()也会接受输入。每次按下Enter键或遇到行尾时,它将递增索引10处的值。所以只需在最后一个循环中添加一个条件以避免打印。或者您可以参考其他一些来源来检查getchar()如何避免输入键或行尾。
我也使用了Phil Kiener给出的建议。
#include <stdio.h>
int main()
{
int c, i;
int chartype[256] = { 0 }; // maximum value for an unsigned char
while((c = getchar()) != EOF) {
++chartype[c]; // no need to subtract '0'
}
for(i = 0; i < 255; ++i) {
if(chartype[i] > 0 && i!='\n') { //avoiding printing value present at index 10
printf("%c, %d\n", i, chartype[i]);
}
}
return 0;
}
答案 1 :(得分:0)
这里的问题是方括号内的c - '0'
。
当你输入'A'时,它应该增加索引为65的整数,这样当你打印值为65的字符时,它会给你'A'。
相反,您正在递增索引位置c - '0'
中的整数,即c - 48
。在这里,当你输入'A'时,它会增加整数17(65 - 48),这是一些特殊字符。
只需放置++chartype[c];
,就可以增加数组中的正确位置并解决问题。
两个旁白:
c - '0'
仅在您的输入是一串数字时使用,并且您想要计算数组的第0个位置中的'0'的次数等。
您不需要为简单的字符分配如此大的数组。 c
有256个可能的值,因此256的MAXLEN
就足够了。
答案 2 :(得分:0)
你的代码可能会混淆了一些东西。
int chartype[MAXLEN];
您希望存储字符在数组中出现的频率,其中每个索引对应一个字符。但是没有1000个字符,只有256个字符。
++chartype[c - '0'];
“成语”c - '0'
通常用于从数字中快速获取数值('9'
变为9
);你不想在这里这样做。
要实际计算字符出现的频率,请执行以下操作:
#include <stdio.h>
int main()
{
int c, i;
int chartype[256] = { 0 }; // maximum value for an unsigned char
while((c = getchar()) != EOF) {
++chartype[c]; // no need to subtract '0'
}
for(i = 0; i < 256; ++i) {
if(chartype[i] > 0) {
printf("%c, %d\n", i, chartype[i]);
}
}
return 0;
}
getchar()
返回unsigned char
,投放到int
以容纳EOF
,因此长度为256的数组足以捕获所有字符。
int chartype[256] = { 0 };
将该数组中的所有值初始化为0
,因此您不需要第一个循环。
(另外,chartype
是一个不好的名字。char_frequency
或类似的东西在可读性方面会更好。)
答案 3 :(得分:0)
这里的问题是你的索引。你可能有小写字母,大写字母和数字(忽略我假设的符号)。由于大写字母从ascii的65开始,48的数字和97的小写字母,我建议使用三个表来计算每个表,并使用isupper和string.h提供的isdigit方法。如果这是一个禁止使用string.h的大学练习,那么我建议使用以下伪代码
If character larger or equal to a
Remove 97, increment position in lowercase letters array
Else if larger or equal to A
Remove 65, increment position in uppercase letters array
Else
Remove 48, increment position in digits array
答案 4 :(得分:0)
++chartype[c - '0'];
可以轻松写入[0 ... MAXLEN)的界限。
示例' ' - '0'
可以是32 - 48或-16。最好基于零进行抵消。
使chartype[];
大到足以使用任何unsigned char
作为索引。有UCHAR_MAX + 1
可能unsigned char
。 fgetc()
会返回unsigned char
或EOF
范围内的值。
#include <limits.h>
...
// int chartype[MAXLEN]; // not right sized
int chartype[UCHAR_MAX + 1];
足够将 chartype[]
元素初始化为零。
int chartype[UCHAR_MAX + 1] = {0};
基于零偏移而不是字符 '0'
进行增量和打印。
while((c = getchar()) != EOF){
// chartype[c - '0']
++chartype[c];
}
for (int i = 0; i <= UCHAR_MAX; i++) {
if(chartype[i]>0) {
printf("%c, %d\n", i, chartype[i]);
}
}
注意:unsigned char
范围达到/超出int
范围的稀有平台需要不同的代码。