我需要编写一个在文本文件中输出字母频率的程序。它读取其他文本文件的文本。问题是大多数字母都被正确计算,但有些字母的频率不正确。有人可以帮我解决这个问题吗?
谢谢!
#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%
答案 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);