C 为什么';我的字符计数器不能正常工作吗?

C 为什么';我的字符计数器不能正常工作吗?,c,C,我最近开始学习C语言,我正在尝试编写一个简单的程序,它应该返回一个字符被使用的次数,但是输出是错误的。 为什么它不能正常工作?任何帮助都将不胜感激。 代码如下: #include <stdio.h> main() { int c, i; int ndigit[25]; //a = 97 while( (c = getchar()) != EOF) { ++ndigit[c - 97]; } for (i =

我最近开始学习C语言,我正在尝试编写一个简单的程序,它应该返回一个字符被使用的次数,但是输出是错误的。 为什么它不能正常工作?任何帮助都将不胜感激。 代码如下:

#include <stdio.h>

main() {
    int c, i;
    int ndigit[25]; //a = 97

    while( (c = getchar()) != EOF) {    
        ++ndigit[c - 97];
    }
    
    for (i = 0; i < 26; i++) {  
        putchar(i + 97);
        printf(" = %d\n", ndigit[i]);
    }
}

创建新数组时,它可能包含随机数。您需要手动将其设置为0s。一种方法是使用以下功能:

memset(ndigit,0,sizeof(int)*26);
您还需要包含string.h才能使用它

编辑:忘记了数组的类型是int,所以我们需要将大小乘以int的大小


Edit2:另外,我认为您希望数组的大小为26

您的问题是数组可能包含随机值。在
C/C++
中,不能保证在程序开始时内存会被清零,相反,您可能会得到以前的内存。如上所述,您可以使用一些内置函数,但只需执行以下操作:

int ndigit[26]; // as mentioned in comments and in previous answers English alphabet has 26 characters

for (int i = 0; i < 26; ++i)
   ndigit[i] = 0;

// rest of you code here
Per@superior您也可以使用

ndigit[26] = {0}
然而,这是C99标准,不严格遵循它的come编译器将不会初始化数组。我知道4.xx之前的gcc版本没有

编辑: 这是我的输出,带有您的(OP代码)和输入
hello

a = 4543
b = 0
c = 0
d = 0
e = 1318238529
f = 32604
g = 121
h = 1
i = 37
j = 57
k = 1136
l = 2
m = 1
n = 0
o = 4195998
p = 0
q = 142
r = 0
s = 0
t = 0
u = 4195920
v = 0
w = 4195568
x = 0
y = -1400909520
z = 32767
这是我的答案的输出,带有
for()
循环和建议的
{0}

a = 0
b = 0
c = 0
d = 0
e = 1
f = 0
g = 0
h = 1
i = 0
j = 0
k = 0
l = 2
m = 0
n = 0
o = 1
p = 0
q = 0
r = 0
s = 0
t = 0
u = 0
v = 0
w = 0
x = 0
y = 0
z = 0
我目前正在尝试编写一个简单的程序,它应该返回一个字符被使用的次数

这是一个相当好的开始练习

以下注意事项将更容易更快地获得结果:

  • 使用编译器的能力来帮助您
    • 如果您正在使用gcc或clang:
      -stdc18-Wall-Wextra-pedantic-pedantic errors
您会注意到wour
main()
函数无效。C不允许使用无类型函数。正确的
main
需要隐式或显式返回
int
。如果有疑问,只需知道默认情况下它将
返回0

也不能初始化数组。这会产生一些后果——比如不知道从记忆中阅读时会发生什么


建议修复该程序,不要使用幻数。这是一个陷阱(假设
97
早在
'a'
将过时很久)。使用
'a'
——或者更好地使用C库中的常量

一旦unicode开始使用,下面的所有内容都会出错,但它很好地计算“字节”值

#include <stdio.h>
#include <string.h>
#include <limits.h> /* UCHAR_MAX (almost never anything but 255) */

char friendlify(unsigned char x) { /* unsigned to char cast ... */
    /* this is just for presentation - purely ASCII friendly */
    /* ternary operator: (condition) ? (true) : (false) */
    return x < '.' || x > '~' ? '.' : x;
}

int main() {
    int c;
    /* make room for all `char`s (unsigned chars really) */
    unsigned ndigit[UCHAR_MAX+1] = {0}; /* zero initialize */

    while ((c = getchar()) != EOF) {
        /* since getchar returns an unsigned - (unless EOF) we're not worried here) */
        ++ndigit[c];
    }

    printf("Collected:\n");
    for (unsigned i = 0; i <= UCHAR_MAX ; ++i) {
        /* just print characters included in the input */
        if (ndigit[i]) { /* assuming zero hits aren't interesting */

            /* %02X and the `i` makes it print the hex value of that particular byte */
            printf("0x%02X  %c  Count = %u\n", i, friendlify(i), ndigit[i]);
        }
    }
}
#包括
#包括
#包括/*UCHAR_MAX(几乎不包括255以外的任何内容)*/
字符友好性(无符号字符x){/*无符号到字符转换*/
/*这只是为了演示-纯粹的ASCII友好*/
/*三元运算符:(条件)?(真):(假)*/
返回x<'.| | x>'~'?':x;
}
int main(){
INTC;
/*为所有“字符”腾出空间(实际上是未签名的字符)*/
无符号ndigit[UCHAR_MAX+1]={0};/*零初始化*/
而((c=getchar())!=EOF){
/*因为getchar返回一个未签名的-(除非EOF)我们在这里不担心)*/
++ndigit[c];
}
printf(“已收集:\n”);

对于(无符号i=0;i您想当然地认为,
getchar
读取的每个字符都是小写字母字符,您的字符集是ascii而不是
c+/-97
您应该使用
c+/-'a'
。并且您的数组没有初始化,这意味着它包含随机数。您应该将所有项设置为0。您可以如果将
ndigit
初始化为大小26,您可以使用“您的代码”包含代码而不缩进。他还可以编写
int ndigit[26]={0}
,将整个数组设置为0s@superior这将在C++ IDK中工作,如果它在C中工作though@CEPB不是实际的doc,但他也可以编写int-ndigit[26]={0}这将整个数组设置为0sLols,@Superior我感谢您的评论,并将其包括在我的回答中,我必须提到这是C99,直到最近一些编译器和Linux distor都有点落后。回答不错,但我认为
C不允许使用无类型函数
不适用于
main()
。默认情况下,它将返回int。@CEPB谢谢!但是,关于
main
:不,它不会返回。
main
需要声明
int
,否则您的程序无效。它是否包含在C99中?LOL刚刚找到它,它在
C99
和更高标准中,但是ANSI C和gcc仍然允许函数在不返回ty的情况下运行我认为所有的C标准允许非标准的(通用的)特定的特殊化来允许嵌入的完美。编辑:我以C++为基础的想法——我可能完全错了。
a = 0
b = 0
c = 0
d = 0
e = 1
f = 0
g = 0
h = 1
i = 0
j = 0
k = 0
l = 2
m = 0
n = 0
o = 1
p = 0
q = 0
r = 0
s = 0
t = 0
u = 0
v = 0
w = 0
x = 0
y = 0
z = 0
#include <stdio.h>
#include <string.h>
#include <limits.h> /* UCHAR_MAX (almost never anything but 255) */

char friendlify(unsigned char x) { /* unsigned to char cast ... */
    /* this is just for presentation - purely ASCII friendly */
    /* ternary operator: (condition) ? (true) : (false) */
    return x < '.' || x > '~' ? '.' : x;
}

int main() {
    int c;
    /* make room for all `char`s (unsigned chars really) */
    unsigned ndigit[UCHAR_MAX+1] = {0}; /* zero initialize */

    while ((c = getchar()) != EOF) {
        /* since getchar returns an unsigned - (unless EOF) we're not worried here) */
        ++ndigit[c];
    }

    printf("Collected:\n");
    for (unsigned i = 0; i <= UCHAR_MAX ; ++i) {
        /* just print characters included in the input */
        if (ndigit[i]) { /* assuming zero hits aren't interesting */

            /* %02X and the `i` makes it print the hex value of that particular byte */
            printf("0x%02X  %c  Count = %u\n", i, friendlify(i), ndigit[i]);
        }
    }
}