C++结构体数组程序查看玩家记录时昵称缺失问题求助
C++程序查看玩家记录时昵称无法显示的问题排查与修复
问题描述
开发一款可添加玩家信息的C++程序,程序能正常运行,但选择「查看玩家记录」选项时,玩家昵称无法显示。尝试改用getline()读取字符串后问题仍未解决;单独测试添加和查看功能(不含switch-case)时功能正常,但需要保留switch-case菜单;即使将查看代码直接写在switch的case分支中,问题依旧存在。
核心原因分析
- 玩家数组生命周期错误:
Player playerArr[numPlayers];定义在start:标签之后,每次执行goto start;都会重新创建新数组,之前添加的玩家数据全部丢失,导致查看时显示空昵称。 - 输入缓冲区处理不严谨:
cin >> op读取菜单选项后,输入缓冲区残留的换行符会干扰后续getline()的读取逻辑,可能导致昵称读取异常。 - 平均得分计算逻辑错误:原
computeAve()函数计算的是所有玩家平均得分的平均值,而非单个玩家的平均得分,导致showMax()和showMin()功能完全失效。
修复方案
1. 调整数组定义位置
将玩家数组的定义移到start:标签之前,确保数组在程序运行期间只初始化一次,数据不会因goto跳转丢失。
2. 优化输入缓冲区处理
在cin >> op之后,用cin.ignore(numeric_limits<streamsize>::max(), '\n');彻底清空输入缓冲区,避免残留的换行符影响后续getline();同时调整addRecord()中的缓冲区处理逻辑,保证输入流程顺畅。
3. 修正平均得分计算逻辑
新增getPlayerAve()函数计算单个玩家的平均得分,重构computeTotalAve()计算所有玩家的整体平均得分,修复showMax()和showMin()的功能逻辑。
完整修正代码
#include <iostream> #include <string> #include <iomanip> #include <limits> using namespace std; struct Player { string nickname; int age; int bps1; int bps2; }; void addRecord(Player& record); void viewPlayers(const Player playerArr[], int numPlayers); double getPlayerAve(const Player& player); double computeTotalAve(const Player playerArr[], int numPlayers); void showMax(const Player playerArr[], int numPlayers); void showMin(const Player playerArr[], int numPlayers); int main() { const int numPlayers = 5; Player playerArr[numPlayers] = {}; // 初始化数组,避免垃圾数据 start: cout << "==============================================" << endl; cout << " MENU " << endl; cout << "==============================================" << endl; cout << "1. Add record" << endl; cout << "2. View players records" << endl; cout << "3. Compute total average of all players" << endl; cout << "4. Show player(s) with max average score" << endl; cout << "5. Show player(s) with min average score" << endl; cout << "6. Exit" << endl; int op; cout << "\nEnter your choice: "; cin >> op; // 清空输入缓冲区,避免残留换行符影响后续getline cin.ignore(numeric_limits<streamsize>::max(), '\n'); switch (op) { case 1: for (int i = 0; i < numPlayers; i++) { cout << endl; cout << "ENTER DETAILS FOR PLAYER " << i + 1 << "\n"; addRecord(playerArr[i]); cout << endl; } goto start; break; case 2: viewPlayers(playerArr, numPlayers); goto start; break; case 3: cout << "Total average of all players: " << fixed << setprecision(2) << computeTotalAve(playerArr, numPlayers) << endl; // 显示每个玩家的个人平均得分 for (int i = 0; i < numPlayers; i++) { if (!playerArr[i].nickname.empty()) { cout << "Player " << i + 1 << " average: " << fixed << setprecision(2) << getPlayerAve(playerArr[i]) << endl; } } goto start; break; case 4: showMax(playerArr, numPlayers); goto start; break; case 5: showMin(playerArr, numPlayers); goto start; break; case 6: cout << "Exiting program." << endl; return 0; break; default: cout << "Invalid choice. Please select a valid option." << endl; goto start; break; } return 0; } void addRecord(Player& record) { cout << "Enter player nickname: "; getline(cin, record.nickname); cout << "Enter player age: "; cin >> record.age; cout << "Enter best played score 1: "; cin >> record.bps1; cout << "Enter best played score 2: "; cin >> record.bps2; // 清空缓冲区,避免影响下一次输入 cin.ignore(numeric_limits<streamsize>::max(), '\n'); } void viewPlayers(const Player playerArr[], int numPlayers) { cout << "============================================================================================" << endl; cout << " Nickname Age Best Played Score 1 Best Played Score 2 " << endl; cout << "============================================================================================" << endl; for (int i = 0; i < numPlayers; i++) { cout << setw(28) << left << playerArr[i].nickname; cout << setw(29) << right << playerArr[i].age; cout << setw(18) << right << playerArr[i].bps1; cout << setw(29) << right << playerArr[i].bps2 << endl; } } double getPlayerAve(const Player& player) { return static_cast<double>(player.bps1 + player.bps2) / 2.0; } double computeTotalAve(const Player playerArr[], int numPlayers) { double totalAverage = 0.0; int validPlayers = 0; for (int i = 0; i < numPlayers; i++) { if (!playerArr[i].nickname.empty()) { totalAverage += getPlayerAve(playerArr[i]); validPlayers++; } } return validPlayers > 0 ? totalAverage / validPlayers : 0.0; } void showMax(const Player playerArr[], int numPlayers) { double maxAverage = 0.0; // 先找出最高的个人平均得分 for (int i = 0; i < numPlayers; i++) { if (playerArr[i].nickname.empty()) continue; double average = getPlayerAve(playerArr[i]); if (average > maxAverage) { maxAverage = average; } } cout << "Player(s) with maximum average score: " << fixed << setprecision(2); for (int i = 0; i < numPlayers; i++) { if (playerArr[i].nickname.empty()) continue; double average = getPlayerAve(playerArr[i]); if (average == maxAverage) { cout << playerArr[i].nickname << " "; } } cout << "(Average: " << maxAverage << ")" << endl; } void showMin(const Player playerArr[], int numPlayers) { double minAverage = 100.0; // 初始化较高值 int validPlayers = 0; // 先找出最低的个人平均得分 for (int i = 0; i < numPlayers; i++) { if (playerArr[i].nickname.empty()) continue; validPlayers++; double average = getPlayerAve(playerArr[i]); if (average < minAverage) { minAverage = average; } } if (validPlayers == 0) { cout << "No players added yet." << endl; return; } cout << "Player(s) with minimum average score: " << fixed << setprecision(2); for (int i = 0; i < numPlayers; i++) { if (playerArr[i].nickname.empty()) continue; double average = getPlayerAve(playerArr[i]); if (average == minAverage) { cout << playerArr[i].nickname << " "; } } cout << "(Average: " << minAverage << ")" << endl; }
额外优化建议
- 替换
goto语句:用while(true)循环实现菜单重复显示,代码结构更清晰,符合现代C++编程规范。 - 增加添加灵活性:允许用户选择添加单个玩家,而非一次性添加5个。
- 数据持久化:将玩家数据保存到本地文件,避免程序退出后数据丢失。
内容的提问来源于stack exchange,提问作者MGN
相关产品推荐
相关产品推荐

