c 以直方图的形式统计输入文件的每种字符出现频率

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define NUM_CHARS 128

int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Usage: %s <filename>\n", argv[0]);
        return 1;
    }

    FILE *file;
    int c;
    int char_frequencies[NUM_CHARS] = {0};


    if ((file = fopen(argv[1], "r")) == NULL) {
        printf("Error: Unable to open file '%s'\n", argv[1]);
        return 1;
    }
    
    // 实现字符频率统计
    while ((c = fgetc(file)) != EOF) {
        if (isascii(c)) { // 判断是否为ASCII字符
            char_frequencies[c]++; // 每种字符在ASCII中都有对应的索引,这个数组正好一一映射
        }
    }


    /*
            判断字符是否为可打印字符的目的是为了确保直方图输出的可读性和易理解性。
        在ASCII码中,除了表示字符的ASCII码值(0~127)外,还有一些控制字符,如换行
        符、制表符、回车符等,这些字符在文本中不可见,并且输出它们可能会导致直方图
        失去可读性。
    */
    printf("字符出现频率直方图:\n");
    for (int i = 0; i < NUM_CHARS; i++) {
        if (char_frequencies[i] > 0 && isprint(i)) { // 判断是否为可打印字符,并且字符是否出现过
            printf("%c: ", i);
            for (int j = 0; j < char_frequencies[i]; j++) {
                printf("■");
            }
            printf("\n");
        }
    }

    fclose(file);
    return 0;
}
  • #include <stdio.h>:包含标准输入输出库,提供了文件操作和输入输出功能。
  • #include <stdlib.h>:包含标准库,提供了一些常用的函数和类型。
  • #include <ctype.h>:包含字符处理函数库,用于字符分类和转换。
  • #define NUM_CHARS 128:定义了常量**NUM_CHARS**,表示ASCII码字符的数量,取值为128。
  • int main(int argc, char *argv[]):程序的入口函数,接受命令行参数。
  • if (argc != 2):检查命令行参数数量是否正确,如果不是2个参数,打印使用说明并退出程序。
  • FILE *file;:声明了一个文件指针**file**,用于打开和操作文件。
  • int c;:声明了一个整型变量**c**,用于存储读取的字符。
  • int char_frequencies[NUM_CHARS] = {0};:声明了一个整型数组**char_frequencies**,用于记录每个字符的出现频率,初始化为0。
  • if ((file = fopen(argv[1], "r")) == NULL):打开命令行参数指定的文件,如果文件打开失败,则打印错误信息并退出程序。
  • while ((c = fgetc(file)) != EOF):逐个读取文件中的字符,直到文件结束。
  • if (isascii(c)):判断字符是否为ASCII字符。
  • char_frequencies[c]++;:根据字符的ASCII码值,将对应位置的频率加1。
  • printf("字符出现频率直方图:\n");:打印输出直方图标题。
  • for (int i = 0; i < NUM_CHARS; i++):遍历ASCII码字符范围。
  • if (char_frequencies[i] > 0 && isprint(i)):判断字符是否出现过且是否为可打印字符。
  • printf("%c: ", i);:打印输出当前字符。
  • for (int j = 0; j < char_frequencies[i]; j++):根据字符频率,输出相应数量的字符,用于表示直方图。
  • printf("\n");:打印换行符,用于分隔不同字符的直方图。
  • fclose(file);:关闭文件,释放资源。
  • return 0;:返回程序执行成功的标志
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。针对你的第一个问题,我可以为你提供一个 Python 代码实现: ```python from collections import Counter # 读取文件内容 with open('filename.txt', 'r') as f: content = f.read() # 统计字符出现次数 counter = Counter(content.lower()) # 打印结果 for char, count in counter.items(): print(f'{char}: {count}') ``` 其中,使用了 Python 的 `collections` 模块中的 `Counter` 类来统计字符出现次数。`lower()` 方法将所有字符转换为小写,以便不区分大小写。你只需要将代码中的 `filename.txt` 替换为你要统计文件名即可。 至于你的第二个问题,实现一个图形用户界面的程序需要用到一些 GUI 库,如 PyQt、Tkinter 等。这里以 PyQt 为例,提供一个简单的代码实现: ```python import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QVBoxLayout class CharacterCounter(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): # 创建标签和文本框 self.file_label = QLabel('输入文件名:') self.file_text = QLineEdit() self.result_label = QLabel() # 创建布局并添加控件 vbox = QVBoxLayout() vbox.addWidget(self.file_label) vbox.addWidget(self.file_text) vbox.addWidget(self.result_label) # 设置窗口布局并显示 self.setLayout(vbox) self.setWindowTitle('字符计数器') self.show() def count_characters(self): # 读取文件内容 filename = self.file_text.text() with open(filename, 'r') as f: content = f.read() # 统计字符出现次数 counter = {} for char in content.lower(): if char.isalpha(): counter[char] = counter.get(char, 0) + 1 # 生成直方图 histogram = '' for char in sorted(counter.keys()): histogram += f'{char}: {"*" * counter[char]}\n' # 显示结果 self.result_label.setText(histogram) if __name__ == '__main__': app = QApplication(sys.argv) ex = CharacterCounter() sys.exit(app.exec_()) ``` 在这个程序中,我们使用了 PyQt5 库创建一个名为 `CharacterCounter` 的窗口类,其中包含一个标签、一个文本框和一个标签。用户可以在文本框中输入文件名,然后单击按钮触发 `count_characters` 方法来统计字符出现次数,并将结果显示在第二个标签中。 你可以运行这个程序来查看效果,注意需要安装 PyQt5 库。使用命令 `pip install pyqt5` 可以安装该库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值