繁体   English   中英

C文件中最常见的字符

[英]Most common character in a file in C

我正在做C编程课程作业,我需要在给定的文件中找到一个最普通的字符。

我使用测试文件,空文件和其他少量文本文件进行的测试效果很好(或者至少我认为是这样),但是在最后一个较长的测试文件中出了点问题,错误消息是: “应该返回'e'(101)for文件rfc791.txt。您返回了'b'(98)“

所以我要问的是,我的代码可能出什么问题了,而突然之间最普通的字母不应该是什么?

int most_common_character(char *filename) {
    FILE *f;
    if ((f = fopen(filename, "r")) == NULL) {
        fprintf(stderr, "Not opened: %s\n", strerror(errno));
        return -1;
    }

    char frequency[26];
    int ch = fgetc(f);
    if (ch == EOF) {
        return 0;
    }

    for (ch = 0; ch < 26; ch++) {
        frequency[ch] = 0;
    }

    while (1) {
        ch = fgetc(f);
        if (ch == EOF) {
            break;
        }
        if ('a' <= ch && ch <= 'z') {
            frequency[ch - 'a']++;
        }
        else if ('A' <= ch && ch <= 'Z') {
            frequency[ch - 'A']++;
        }
    }
    int maxCount = 0;
    int maxChar = 0;
    for (int i = 0; i <= 26; ++i) {
        if (frequency[i] > maxCount) {
            maxCount = frequency[i];
            maxChar = i;
        }
    }
    fclose(f);
    return maxChar + 'a';
}

如果有人有任何修复我的代码的提示,我将不胜感激:)我试图从许多其他相关主题中搜索此问题的解决方案,但似乎无济于事。

您应该在第二个for循环中使用<运算符。 因此,当您检查frequency [i]> maxCount时,在frequency [26]时,它表现为未定义的行为,这意味着该索引处的值可能小于或大于比较值。

您的代码确实存在一些问题。 但是,它们是如此之小,因此代码仍然可以在小型测试中很好地工作。

  1. int ch = fgetc(f); 删除文件中的第一个字符

  2. for (int i = 0; i <= 26; ++i)超出数组的范围(仅从0-> 25)

除了这些小错误之外,您的代码还不错。 做得好#thumbsup

  1. 循环越界。 @风向标

     // for (int i = 0; i <= 26; ++i) { for (int i = 0; i < 26; ++i) { 
  2. 代码将丢弃第一个字符的结果。 @BLUEPIXY

     int ch = fgetc(f); if (ch == EOF) { return 0; } // This value of ch is not subsequently used. 

其他修复如下

int most_common_character(char *filename) {
    ...

    // Use a more generous count @Weather Vane
    // char frequency[26];
    // Consider there may be more than 26 different letters
    // fgetc return EOF and value in the unsigned char range
    int frequency[UCHAR_MAX + 1] = { 0 };

    // Not needed as array was initialize above
    // for (ch = 0; ch < 26; ch++) { frequency[ch] = 0; }

    // BTW correct type declaration of int, avoided rookie mistake of using char
    int ch;

    // Codes use tolower(), islower() as that is the portable way to 
    // handle type-of-character detection
    while ((ch = fgetc(f)) != EOF) {
      frequency[tolower(ch)]++;  // could add check to insure frequency[] does not overflow
    } 

    int maxCount = 0;
    int maxChar = -1;
    for (int i = 0; i <= UCHAR_MAX; ++i) {
      if (islower(i) && frequency[i] > maxCount) {
        maxCount = frequency[i];
        maxChar = i;
      }
    }

    fclose(f);
    return maxChar;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM