为何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
问题原因
- 局部变量未初始化:每个函数中的
char ch;未初始化,第一次进入while (ch != EOF)时,ch的值是随机内存值,属于未定义行为。如果随机值恰好等于EOF(-1),循环直接跳过,输出0;反之则能正常执行。 - 类型不匹配:
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
相关产品推荐
相关产品推荐

