C程序不计算文本文件中的字母频率

时间:2016-01-17 14:37:12

标签: 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 *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;
}

输入文件是:

Hi my name is niels and i a tying to write code.

输出文件包含:

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%

4 个答案:

答案 0 :(得分:1)

问题是你在将数组归零的循环中错误放置了主代码。
变化:

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) {

return 0之前删除大括号,然后你就完成了。

答案 1 :(得分:0)

您永远不会初始化letters数组。未初始化的变量将包含导致您正在观察的行为的未知值。它也是未定义的行为

尝试

int letters[26] = {0};

答案 2 :(得分:0)

以下似乎嵌套在另一个for循环中,从0到25.嵌套循环和外循环也都使用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);

    }
}

看起来你要给我打字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);

    }
}

答案 3 :(得分:-1)

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

int letters[26] = { 0 };

或(使用来自string.h的memset

int letters[26];
memset(letters, 0, 26);