C++统计文本字符频率代码返回-1073741819错误排查求助
错误原因排查
你遇到的Process returned -1073741819 (0xC0000005)是Windows平台下的内存访问违例错误,核心问题确实和数组下标越界有关,具体原因如下:
- 多数C++编译器中
char默认是有符号类型,取值范围为-128 ~ 127。你要统计的俄文大写西里尔字母А到Я在CP1251编码下对应十进制值为192 ~ 223,超过了有符号char的正数值范围,存入char类型变量时会被转为负数,用负数作为数组下标访问freq数组时直接越界,触发内存访问错误。 - 额外隐患1:
toupper函数的入参要求是unsigned char类型转换的int值或EOF,如果传入负数(非EOF)会触发未定义行为。 - 额外隐患2:输出循环用
char类型遍历А到Я,有符号char超过127后会溢出回绕为负数,会导致循环永远无法满足退出条件,进入死循环。 - 可选优化:当前没有判断文件是否打开成功,如果
abc.txt不存在或路径错误,代码不会崩溃但无法得到统计结果。
修复方案
修改后可正常运行的代码如下:
#include <bits/stdc++.h> int main() { setlocale(LC_ALL, "Russian"); int freq[256] = {0}; // 支持直接批量初始化,无需单独循环赋值 std::ifstream inFile("abc.txt"); unsigned char ch; // 改用无符号char,避免负数问题 // 增加文件打开成功校验 if (!inFile.is_open()) { std::cout << "文件打开失败,请检查路径是否正确" << std::endl; return 1; } int read_ch = inFile.get(); while (read_ch != EOF) { ch = static_cast<unsigned char>(read_ch); ch = toupper(ch); freq[ch]++; read_ch = inFile.get(); } // 输出统计结果,遍历用unsigned char避免溢出死循环 std::cout << "Letter frequencies in this file are as follows." << std::endl; for (unsigned char ch = 'А'; ch <= 'Я'; ch++) { std::cout << ch << ": " << freq[ch] << std::endl; } return 0; }
内容的提问来源于stack exchange,提问作者user15761564
相关产品推荐
相关产品推荐

