凯撒密码程序 - 数组输出中的荒谬数字

时间:2012-02-09 07:25:17

标签: c

我实际上是在编写与以前相同的程序,但我觉得自上次以来我取得了重大进展。但是我有一个新问题;我有一个函数,用于存储数组中消息中包含的字母频率,以便稍后进行一些比较检查。当我通过函数运行测试段时输出所有数组条目以查看它们的值是什么,它似乎存储了一些荒谬的数字。这是问题的功能:

void calcFreq ( float found[] ) 
{
    char infname[15], alpha[27];
    char ch;
    float count = 0;
    FILE *fin;

    int i = 0;
    while (i < 26) {
        alpha[i] = 'A' + i++;
    }

    printf("Please input the name of the file you wish to scan:\n");
    scanf("%s", infname);

    fin = fopen ( infname, "r");
    while ( !feof(fin) ) {
        fscanf(fin, "%c", &ch);
        if ( isalpha(ch) ) {
            count += 1;
            i = 0;
            if ( islower(ch) ) { ch = toupper(ch); }
            while ( i < 26 ) {
                if ( ch == alpha[i] ) {
                    found[i]++;
                    i = 30;
                }
                i++;
            }
        }
    }
    fclose(fin);
    i = 0;
    while ( i < 26 ) {
        found[i] = found[i] / count;
    printf("%f\n", found[i]);
        i++;
    }
}

在...发现[5],我得到了存储在那里的非常荒谬的数字。有什么你可以看到我只是俯瞰?此外,一些数组值为0,我很确定字母表中的每个字符在我正在使用的文本文件中至少使用过一次。

我觉得自己像个白痴 - 这个程序应该很容易,但我一直在忽略那些花费我很多时间的简单错误&gt;。&gt;非常感谢你的帮助。

编辑所以...我将频率数组的条目设置为0,看起来似乎没问题 - 在Linux环境中。当我尝试从Windows环境使用IDE时,程序什么也不做,Windows崩溃了。到底是什么?

3 个答案:

答案 0 :(得分:1)

alpha[i] = 'A' + i++;

这是C中的未定义行为。执行此操作时可能会发生任何事情,包括崩溃。阅读this link

一般情况下,当已知最大迭代次数时,我建议您使用for循环替换while循环。这使代码更容易阅读,也可能更快。

您是否有使用float作为计数器变量的原因?这没有意义。

'我= 30;'这应该是什么意思?如果你打算结束循环,请使用break语句而不是一些神秘的幻数。如果你的意图是别的,那么你的代码就没有按照你的想法去做。

如果找不到文件,您应该包含一些错误处理。 fin = fopen(..)然后if(fin == NULL)处理错误。我想说这是造成事故的最可能原因。

答案 1 :(得分:1)

除了初始化found[]中最重要的一点之外,还有一些指示,其他评论中提到了这一点。

alpha[]数组使事情复杂化,而您不需要它。请参阅下面的修改后的文件读取循环,它不需要alpha[]数组来计算文件中的字母数。

严格来说,您用来初始化alpha[]数组的表达式:

alpha[i] = 'A' + i++;

具有未定义的行为,因为您修改了i并将其用作表达式的两个不同部分中的索引。好消息是,由于你不需要alpha[],你可以完全摆脱它的初始化。

您检查EOF的方式不正确 - 这会导致您对文件中的最后一个字符进行两次操作(因为fscanf()调用导致EOF }不会更改ch)的值。在之后在文件末尾发生的读取之后,feof()才会返回true。将您的ch变量更改为int类型,并将读取文件的循环修改为:

// assumes that `ch` is declared as `int`

while ( (ch = fgetc(fin)) != EOF ) {
    if ( isalpha(ch) ) {
        count += 1;
        ch = toupper(ch);

        // the following line is technically non-portable, 
        //  but works for ASCII targets.
        // I assume this will work for you because the way you
        //  initialized the `alpha[]` array assumed that `A`..`Z`
        //  were consecutive.

        int index = ch - 'A';

        found[index] += 1;
    }
}

答案 2 :(得分:0)

检查调用函数中found []的定义。你可能已经没法了。