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

为何C语言中多个同类文件读取函数仅第一个正常执行?

问题:C语言文件统计函数仅首个调用有效,后续函数输出为0

现有一段C语言代码,包含3个用于统计文件内容的函数(统计元音、辅音、字母总数),目标文件名为"mno"。但实际运行时,仅main函数中第一个被调用的函数能正常输出结果:比如先调用countVowel能得到正确的10,后续countConsonant和countAlphabet都输出0;若注释countVowel,仅countConsonant能正常工作,countAlphabet仍输出0,以此类推。

原代码

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

void countVowel(char fin[])
{
  FILE *fl;
  char ch;
  int count = 0;
  fl = fopen(fin, "r");
  while (ch != EOF)
  {
    ch = tolower(fgetc(fl));
    count += (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') ? 1 : 0;
  }
  fclose(fl);
  printf("Number of Vowels in the file \" %s \"-> \t %d \n", fin, count);
}

void countConsonant(char fin[])
{
  FILE *fl;
  char ch;
  int count = 0;
  fl = fopen(fin, "r");
  while (ch != EOF)
  {
    ch = tolower(fgetc(fl));
    count += (!(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') && (ch >= 'a' && ch <= 'z')) ? 1 : 0;
  }
  fclose(fl);
  printf("Number of Consonant in the file \" %s \"-> \t %d \n", fin, count);
}

void countAlphabet(char fin[])
{
  FILE *fl;
  char ch;
  int count = 0;
  fl = fopen(fin, "r");
  while (ch != EOF)
  {
    ch = tolower(fgetc(fl));
    count += (ch >= 'a' && ch <= 'z') ? 1 : 0;
  }
  fclose(fl);
  printf("Number of Alphabets in the file \" %s \"-> \t %d \n", fin, count);
}

int main()
{
  countVowel("mno"); // output -> 10
  countConsonant("mno"); // output -> 0
  countAlphabet("mno"); // output -> 0
  return 0;
}

目标文件mno内容

qwertyuiopasdfghjklzxcvbnm, QWERTYUIOPASDFGHJKLZXCVBNM, 1234567890

问题原因

  1. 局部变量未初始化:每个函数中的char ch;未初始化,第一次进入while (ch != EOF)时,ch的值是随机内存值,属于未定义行为。如果随机值恰好等于EOF(-1),循环直接跳过,输出0;反之则能正常执行。
  2. 类型不匹配:fgetc返回int类型(有效字符为0~255,EOF为-1),但代码中用char存储返回值。若char是无符号类型,-1会被转换为255,导致ch != EOF永远为真,循环无限执行;即使是有符号char,读取到0xFF字符时也会被误判为EOF。

修复方案

  • 将char ch;改为int ch;,匹配fgetc的返回值类型;
  • 调整循环逻辑,先读取字符再判断是否为EOF,避免依赖未初始化变量。

修复后的代码

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

void countVowel(char fin[])
{
  FILE *fl;
  int ch; // 改为int类型
  int count = 0;
  fl = fopen(fin, "r");
  // 先读取再判断,避免未初始化变量
  while ((ch = fgetc(fl)) != EOF)
  {
    ch = tolower(ch);
    count += (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') ? 1 : 0;
  }
  fclose(fl);
  printf("Number of Vowels in the file \" %s \"-> \t %d \n", fin, count);
}

void countConsonant(char fin[])
{
  FILE *fl;
  int ch; // 改为int类型
  int count = 0;
  fl = fopen(fin, "r");
  while ((ch = fgetc(fl)) != EOF)
  {
    ch = tolower(ch);
    count += (!(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') && (ch >= 'a' && ch <= 'z')) ? 1 : 0;
  }
  fclose(fl);
  printf("Number of Consonant in the file \" %s \"-> \t %d \n", fin, count);
}

void countAlphabet(char fin[])
{
  FILE *fl;
  int ch; // 改为int类型
  int count = 0;
  fl = fopen(fin, "r");
  while ((ch = fgetc(fl)) != EOF)
  {
    ch = tolower(ch);
    count += (ch >= 'a' && ch <= 'z') ? 1 : 0;
  }
  fclose(fl);
  printf("Number of Alphabets in the file \" %s \"-> \t %d \n", fin, count);
}

int main()
{
  countVowel("mno"); // 输出10
  countConsonant("mno"); // 输出42
  countAlphabet("mno"); // 输出52
  return 0;
}

内容的提问来源于stack exchange,提问作者d3v-anaxa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:25:31