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

C++结构体数组程序查看玩家记录时昵称缺失问题求助

C++程序查看玩家记录时昵称无法显示的问题排查与修复

问题描述

开发一款可添加玩家信息的C++程序,程序能正常运行,但选择「查看玩家记录」选项时,玩家昵称无法显示。尝试改用getline()读取字符串后问题仍未解决;单独测试添加和查看功能(不含switch-case)时功能正常,但需要保留switch-case菜单;即使将查看代码直接写在switch的case分支中,问题依旧存在。

核心原因分析

  1. 玩家数组生命周期错误:Player playerArr[numPlayers];定义在start:标签之后,每次执行goto start;都会重新创建新数组,之前添加的玩家数据全部丢失,导致查看时显示空昵称。
  2. 输入缓冲区处理不严谨:cin >> op读取菜单选项后,输入缓冲区残留的换行符会干扰后续getline()的读取逻辑,可能导致昵称读取异常。
  3. 平均得分计算逻辑错误:原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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:03:10