You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++使用C风格IO读取文本统计元音并筛选写入新文件问题求解

问题解答

异常原因

你遇到的统计错误核心是字符串遍历逻辑错误:

  • C语言中fgets读取到的内容是合法的C风格字符串,会在有效内容的末尾自动添加\0作为结束标志,数组中超出有效长度的位置是未初始化的垃圾值
  • 你当前的循环固定遍历1024个数组元素,会把有效内容后的垃圾值也纳入统计,自然会得到错误的元音计数
    除此之外你的代码还有几处隐性问题:
  • 未校验文件打开结果:如果输入文件不存在、无读写权限,fopen会返回空指针,后续读写操作会直接触发崩溃
  • 仅统计了小写元音,大写A/E/I/O/U未纳入计数,会出现漏算
  • 输出文件使用a+追加模式,多次运行程序会导致结果累加,通常这类单次统计需求建议使用w模式每次清空重写
  • 额外的ASCII范围判断逻辑没有必要,不可见字符不存在元音字母,该判断反而可能漏掉合法的特殊字符统计

修正后的完整代码

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

void voals_text()
{
    FILE *input_file = fopen("questions.txt", "r");
    FILE *output_file = fopen("result.txt", "w");
    // 校验文件打开是否成功
    if (input_file == NULL || output_file == NULL) {
        perror("文件打开失败");
        return;
    }
    
    char line[1024];
    int nr_voals = 0;
    while (fgets(line, sizeof(line), input_file) != NULL) {
        nr_voals = 0;
        // 遍历到字符串结束符'\0'就停止,不会读取垃圾值
        for (int i = 0; line[i] != '\0'; i++) {
            // 统一转小写,同时统计大小写元音
            char c = tolower(line[i]);
            if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
                nr_voals++;
            }
        }
        // 元音数为偶数就写入输出文件
        if (nr_voals % 2 == 0) {
            fputs(line, output_file);
        }
    }

    fclose(input_file);
    fclose(output_file);
}

int main()
{
    voals_text();
    return 0;
}

更优化的实现方案

如果需要支持超过1024字节的长行,可以采用动态缓冲区方案:

  • 初始分配指定大小的缓冲区,用fgets读取内容
  • 判断读取到的内容末尾是否包含换行符,如果未包含说明行未读完,用realloc扩容缓冲区后继续读取剩余内容
  • 统计完成后释放动态缓冲区即可

内容的提问来源于stack exchange,提问作者geekt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 22:45:04