【问题标题】:Most common character in a file in CC语言文件中最常见的字符
【发布时间】:2017-02-06 05:07:15
【问题描述】:

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

我使用 testfile、emptyfile 和其他少量文本文件的测试效果很好(或者至少我认为如此),但在最后一个长的 testfile 中出现了问题,错误消息是:“应该返回 ' e' (101) 用于文件 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 (int i = 0; i &lt;= 26; ++i) 打破了数组边界。
  • 我也不会使用char 数组,它不适用于较大的文件。使用unsigned int
  • 此外,您正在读取并丢弃文件中的第一个字符。
  • 好吧,@WeatherVane 给了你答案。 char 范围不足以容纳您的测试文件。
  • int ch = fgetc(f); 删除一个字符。

标签: c file character


【解决方案1】:

您应该在第二个 for 循环中使用 maxCount 时,在频率 [26] 处,它的行为未定义,这意味着该索引处的值可能小于或大于比较值。

【讨论】:

    【解决方案2】:

    您的代码确实存在一些问题。但是,它们是如此之小,因此代码仍然适用于小型测试。

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

    2. for (int i = 0; i &lt;= 26; ++i) 突破数组的范围(仅从 0-->25)

    除了这些小错误之外,您的代码非常好。干得好#thumbsup

    【讨论】:

      【解决方案3】:
      1. 循环超出范围。 @Weather Vane

        // 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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-12
        • 1970-01-01
        • 1970-01-01
        • 2011-12-08
        • 2023-04-04
        • 2011-03-01
        • 2019-05-19
        • 1970-01-01
        相关资源
        最近更新 更多