C程序没有从文本文件中计算字母频率

C程序没有从文本文件中计算字母频率,c,arrays,file,arguments,frequency,C,Arrays,File,Arguments,Frequency,我需要写一个程序,输出一个文本文件中的字母频率。它读取其他文本文件的文本。问题是,大多数字母的计数都是正确的,但也有少数字母的频率很高,这是不正确的。有人能帮我解决这个问题吗 谢谢大家! #include <stdio.h> #include <stdlib.h> #define NLETTERS 26 int main(int argc, char *argv[]) { int c, i, accum = 0, letter[26]; FILE *i

我需要写一个程序,输出一个文本文件中的字母频率。它读取其他文本文件的文本。问题是,大多数字母的计数都是正确的,但也有少数字母的频率很高,这是不正确的。有人能帮我解决这个问题吗

谢谢大家!

#include <stdio.h>
#include <stdlib.h>

#define NLETTERS 26

int main(int argc, char *argv[])
{
    int c, i, accum = 0, letter[26];
    FILE *ifp, *ofp;

    printf ("argument 0 = argv[0] = '%s'n", argv[0]);
    printf ("argument 1 = argv[1] = '%s'n", argv[1]);
    printf ("argument 2 = argv[2] = '%s'n", argv[2]);

    ifp = fopen(argv[1], "r");
    ofp = fopen(argv[2], "w");

    if (ifp == NULL)
        perror("No input file");

    if (ofp == NULL)
        perror("Trouble making file");

    for (i = 0; i < NLETTERS; i++) {
        letter[i] = 0;

        for(; (c = getc(ifp)) != EOF; ++accum) {
            if (c >='a' && c <= 'z')
                ++letter[c - 'a'];
        }

        for (i = 0; i < NLETTERS; ++i) {
            if (letter[i] != 0) {
                fprintf(ofp, "%c:%5d",i + 'a', letter[i]);
                putc('n', ofp);
                fprintf(ofp, "%f%cnn", ((double)letter[i]/accum), 37);
            }
        }
    }
    return 0;
}
输出文件包含:

a:    3
0.062500%

b:32767
682.645833%

c:1606416521
33467010.854167%

d:32769
682.687500%

e:    7
0.145833%

g:1606416545
33467011.354167%

h:32767
682.645833%

i:    6
0.125000%

j:    1
0.020833%

l:    1
0.020833%

m:1606416578
33467012.041667%

n:32771
682.729167%

o:    2
0.041667%

r:    1
0.020833%

s:    2
0.041667%

t:    3
0.062500%

w:    1
0.020833%

y:1606416530
33467011.041667%

z:32767
682.645833%

从不初始化
字母
数组。未初始化的变量将包含导致您正在观察的行为的未知值。这也是未定义的行为

试一试


如果您声明了一个变量或数组,并且没有初始化它,那么该变量将包含垃圾。在这种情况下,需要将
字母
数组归零。即:

int letters[26] = { 0 };
或者(使用string.h中的
memset


以下内容似乎嵌套在另一个从0到25的for循环中。嵌套循环和外部循环也都使用
i
。这意味着外部循环将永远不会看到i=2,因为内部循环将其移动到25

for (i = 0; i < 26; ++i) {
    if (letter[i] != 0) {
        fprintf(ofp, "%c:%5d",i + 'a', letter[i]);
        putc('n', ofp);
        fprintf(ofp, "%f%cnn", ((double)letter[i]/accum), 37);

    }
}
(i=0;i<26;++i)的
{
如果(字母[i]!=0){
fprintf(of p,“%c:%5d”,i+'a',字母[i]);
putc('n',ofp);
fprintf(ofp,“%f%cnn”,((双)字母[i]/acum),37);
}
}
看起来你会把字母表给我打印26次。你能把上面的代码移出第一个for循环吗

我重写为:

/*for (i = 0; i < 26; i++)
{
    letter[i] = 0;
}*/
letter = {0};

while ((c= getc(ifp)) != EOF) {

    if (c >='a' && c <= 'z')
        ++letter[c-'a'];
    accum++;

}

for (i = 0; i < 26; ++i) {
    if (letter[i] != 0) {
        fprintf(ofp, "%c:%5d",i + 'a', letter[i]);
        putc('n', ofp);
        fprintf(ofp, "%f%cnn", ((double)letter[i]/accum), 37);

    }
}
(i=0;i<26;i++)的
/*
{
字母[i]=0;
}*/
字母={0};
而((c=getc(ifp))!=EOF){

如果(c>='a'&&c问题是您将主代码错误地放在了数组归零的循环中。
更改:

(i=0;i<26;i++)的
{
字母[i]=0;
而((c=getc(ifp))!=EOF){

(i=0;i<26;i++)的
{
字母[i]=0;
}
而((c=getc(ifp))!=EOF){

返回0
之前删除大括号,就完成了。

将字母向量中的所有元素初始化为0:int字母[26]={0};学习如何使用调试器,并逐行检查代码以了解发生了什么。使用此程序应该会非常有启发性。此外,除数字
'0'
-
'9'
之外的字符不保证具有连续表示。
if(c>='a'&&c
int letters[26];
memset(letters, 0, 26);
for (i = 0; i < 26; ++i) {
    if (letter[i] != 0) {
        fprintf(ofp, "%c:%5d",i + 'a', letter[i]);
        putc('n', ofp);
        fprintf(ofp, "%f%cnn", ((double)letter[i]/accum), 37);

    }
}
/*for (i = 0; i < 26; i++)
{
    letter[i] = 0;
}*/
letter = {0};

while ((c= getc(ifp)) != EOF) {

    if (c >='a' && c <= 'z')
        ++letter[c-'a'];
    accum++;

}

for (i = 0; i < 26; ++i) {
    if (letter[i] != 0) {
        fprintf(ofp, "%c:%5d",i + 'a', letter[i]);
        putc('n', ofp);
        fprintf(ofp, "%f%cnn", ((double)letter[i]/accum), 37);

    }
}
for (i = 0; i < 26; i++) {
    letter[i] = 0;

    while ((c= getc(ifp)) != EOF) {
for (i = 0; i < 26; i++) {
    letter[i] = 0;
}

while ((c= getc(ifp)) != EOF) {