C++文本文件词频统计代码问题:计数不更新+菜单无效输入循环
问题修复:词频统计失效与菜单输入异常
问题背景
学校项目中遇到两个核心问题:
- 词频统计失效:文件可正常打开,但所有物品的出现次数始终显示为0;参考Stack Overflow建议修改后编译无错误,但统计列表仍为空,计数未更新。
- 菜单输入异常:输入无效选项时,程序进入无限循环重复打印菜单。
原问题附带的错误表现:
- 读取文件时持续抛出“无效条目”错误
- 显示统计列表时所有物品数量为0
原错误代码
#include <iostream> #include <fstream> #include <map> #include <string> #include <stdexcept> using namespace std; class ItemCounter { private: map <string, int> itemFrequency; string inputFile = "CS210_Project_Three_Input_File.txt"; string outputFile = "itemTracker.dat"; public: void loadInputFile() { ifstream file(inputFile); // OPEN conditions if (file.is_open()) { string itemName; while (getline(file, itemName)) { int itemQuantity = 0; // Update item count itemFrequency[itemName] += itemQuantity; // Exception check for string conversion try { itemQuantity = stoi(itemName); } catch (const invalid_argument& e) { cout << "Error: Invalid Entry Found in Input File." << endl; continue; } } // Close open file file.close(); } // Else statement if file won't open else { cout << "Error: Could Not Open Input File" << endl; cout << endl; } } // Function to save new data to external file void saveOutputFile() { ofstream file(outputFile); if (file.is_open()) { for (auto& item : itemFrequency) { file << item.first << " " << item.second << endl; } file.close(); } else { cout << "Error: Could Not Open Output File - Data Not Saved" << endl; cout << endl; } } // Function to display item occurrences void displayItemCount(string itemName) { int count = itemFrequency[itemName]; cout << "Total Item Occurances for " << itemName << ": " << count << endl; } //Function to count and display total item counts of whole list void displayTotals () { for (auto& item : itemFrequency) { cout << item.first << " " << item.second << endl; } } // Function to count items in the list and print as histogram void displayItemsHistogram() { for (auto& item : itemFrequency) { cout << item.first << " "; for (int i = 0; i < item.second; i++) { cout << "*"; } cout << endl; } } }; // 重复定义的函数,语法错误 void saveOutputFile() { ofstream file(outputFile); if (file.is_open()) { for (auto& item : itemFrequency) { file << item.first << " " << item.second << endl; } file.close(); } else { cout << "Error: Could Not Open Output File - Data Not Saved" << endl; cout << endl; } } }; int main() { ItemCounter itemCounter; itemCounter.loadInputFile(); itemCounter.saveOutputFile(); int menuChoice = 0; while (menuChoice != 4) { cout << "Main Menu" << endl; cout << endl; cout << "1. Stuff" << endl; cout << "2. Stuff" << endl; cout << "3. Stuff" << endl; cout << "4. Exit" << endl; cout << "Please make a selection: "; cin >> menuChoice; cout << endl; if (menuChoice == 1) { string itemName; cout << "Enter search term: "; cin >> itemName; cout << "FIX ME:" << endl; } else if (menuChoice == 2) { cout << "FIX ME" << endl; } else if (menuChoice == 3) { cout << "FIX ME" << endl; } else if (menuChoice == 4) { cout << "Program Terminated" << endl; } else { cout << "Invalid Selection, try again." << endl; } } return 0; }
错误分析
词频统计逻辑完全错误
loadInputFile中,初始化itemQuantity = 0后执行itemFrequency[itemName] += 0,相当于没有任何计数增长。- 错误地尝试将物品名称(字符串)转换为整数,导致每次读取都会触发
invalid_argument异常,执行continue跳过后续逻辑,根本没有完成统计。 - 类外部重复定义了
saveOutputFile函数,属于语法错误(编译时会报错)。
菜单输入异常
- 当输入非整数内容时,
cin >> menuChoice会进入失败状态,后续所有cin操作都会直接失败,导致menuChoice始终为初始值0,触发无限循环打印菜单。
- 当输入非整数内容时,
修复后的代码
#include <iostream> #include <fstream> #include <map> #include <string> #include <stdexcept> #include <limits> using namespace std; class ItemCounter { private: map<string, int> itemFrequency; string inputFile = "CS210_Project_Three_Input_File.txt"; string outputFile = "itemTracker.dat"; public: void loadInputFile() { ifstream file(inputFile); if (file.is_open()) { string itemName; // 直接读取每行物品名称,计数自增 while (getline(file, itemName)) { // 跳过空行避免无效统计 if (itemName.empty()) continue; itemFrequency[itemName]++; } file.close(); } else { cout << "错误:无法打开输入文件" << endl << endl; } } void saveOutputFile() { ofstream file(outputFile); if (file.is_open()) { for (auto& item : itemFrequency) { file << item.first << " " << item.second << endl; } file.close(); } else { cout << "错误:无法打开输出文件 - 数据未保存" << endl << endl; } } void displayItemCount(const string& itemName) { // 使用find避免自动插入不存在的键 auto it = itemFrequency.find(itemName); int count = it != itemFrequency.end() ? it->second : 0; cout << itemName << " 的总出现次数:" << count << endl; } void displayTotals() { cout << "所有物品统计:" << endl; for (auto& item : itemFrequency) { cout << item.first << " " << item.second << endl; } cout << endl; } void displayItemsHistogram() { cout << "统计直方图:" << endl; for (auto& item : itemFrequency) { cout << item.first << " "; for (int i = 0; i < item.second; i++) { cout << "*"; } cout << endl; } cout << endl; } }; int main() { ItemCounter itemCounter; itemCounter.loadInputFile(); itemCounter.saveOutputFile(); int menuChoice = 0; while (menuChoice != 4) { cout << "主菜单" << endl << endl; cout << "1. 查询单个物品出现次数" << endl; cout << "2. 显示所有物品统计" << endl; cout << "3. 显示统计直方图" << endl; cout << "4. 退出" << endl; cout << "请输入选择: "; // 处理输入错误 if (!(cin >> menuChoice)) { cout << endl << "输入无效,请输入数字选项!" << endl << endl; // 清除错误状态 cin.clear(); // 清空输入缓冲区 cin.ignore(numeric_limits<streamsize>::max(), '\n'); continue; } cout << endl; switch(menuChoice) { case 1: { string itemName; cout << "输入查询物品: "; cin >> itemName; itemCounter.displayItemCount(itemName); cout << endl; break; } case 2: itemCounter.displayTotals(); break; case 3: itemCounter.displayItemsHistogram(); break; case 4: cout << "程序已终止" << endl; break; default: cout << "无效选择,请重试。" << endl << endl; } } return 0; }
修复要点
- 词频统计修复:移除错误的整数转换逻辑,直接对读取到的物品名称执行
itemFrequency[itemName]++完成计数;跳过空行避免无效统计。 - 输入错误处理:在读取菜单选项时检查
cin状态,若输入失败则清除错误状态并清空缓冲区,避免无限循环。 - 完善功能调用:替换菜单中的
FIX ME,调用ItemCounter类的对应方法实现功能。 - 修复语法错误:删除类外部重复定义的
saveOutputFile函数。
内容的提问来源于stack exchange,提问作者K_B
相关产品推荐
相关产品推荐

