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

C++使用结构体存储艺人唱片信息 读取文件数据问题求助

C++ 艺人唱片信息程序文件读取实现指导

核心问题梳理

  • 直接使用>>读取带空格的艺人名会截断内容
  • 混合使用>>和getline时,>>会在输入流中残留换行符,导致后续getline读取到空行
  • 没有实现按指定分隔符拆分字符串的逻辑,无法处理多值的流派、专辑字段

解决步骤

1. 实现字符串拆分工具函数

这个函数用来把按分隔符拼接的字符串拆成独立元素的vector,直接放在全局位置即可,注意新增引入<sstream>头文件:

#include <sstream>

vector<string> split(const string& s, char delimiter) {
    vector<string> tokens;
    string token;
    istringstream tokenStream(s);
    while (getline(tokenStream, token, delimiter)) {
        // 去掉字段前后的空格,可根据你的文件格式调整是否保留
        size_t start = token.find_first_not_of(" \t");
        size_t end = token.find_last_not_of(" \t");
        if (start != string::npos && end != string::npos) {
            token = token.substr(start, end - start + 1);
        }
        if (!token.empty()) {
            tokens.push_back(token);
        }
    }
    return tokens;
}

2. 修正operator>>重载逻辑

修改原来的输入运算符重载,处理整行读取和字段拆分:

istream& operator>>(istream& input, Artist& artist) {
    // 先清空原有数据,避免复用对象时残留旧内容
    artist.genres.clear();
    artist.disc.trackTitle.clear();
    artist.disc.trackYear.clear();

    // 读取艺人名(整行读取,支持带空格的名称)
    getline(input, artist.artistName);
    if (artist.artistName.empty() && input.eof()) {
        return input; // 读到文件尾直接返回
    }

    // 读取流派行,按;拆分存入vector
    string line;
    getline(input, line);
    artist.genres = split(line, ';');

    // 读取活跃年份和专辑数量,读完忽略行尾残留的换行符
    input >> artist.startingYear >> artist.endingYear >> artist.numOfTracks;
    input.ignore(); 

    // 读取专辑行,先按;拆分每个专辑条目
    getline(input, line);
    vector<string> albumEntries = split(line, ';');
    for (const string& entry : albumEntries) {
        // 每个专辑条目再按,拆分名称和发行年份
        vector<string> albumInfo = split(entry, ',');
        if (albumInfo.size() >= 2) {
            artist.disc.trackTitle.push_back(albumInfo[0]);
            artist.disc.trackYear.push_back(stoi(albumInfo[1]));
        }
    }
    return input;
}

3. 实现一次性读取所有艺人数据

不要每次调用展示/搜索功能都重新读文件,在程序启动时一次性读取到全局vector中,后续所有功能直接操作内存中的数据即可:

// 全局存储所有艺人数据,原来main函数里的art变量可以替换成这个
vector<Artist> allArtists;

// 新增读取全部文件的函数
void loadAllArtists() {
    ifstream artistFile("My Artists.txt");
    if (!artistFile.is_open()) {
        cout << "文件打开失败,请检查My Artists.txt是否在程序运行目录下" << endl;
        return;
    }
    Artist temp;
    while (artistFile >> temp) {
        allArtists.push_back(temp);
    }
    artistFile.close();
}

在main函数最开头调用loadAllArtists()完成数据加载即可。

4. 修正displayFileContents逻辑

void displayFileContents() {
    if (allArtists.empty()) {
        cout << "暂无艺人数据可展示" << endl;
        return;
    }
    for (const Artist& a : allArtists) {
        cout << "艺人名称:" << a.artistName << endl;
        cout << "流派:";
        for (size_t i=0; i<a.genres.size(); i++) {
            if (i>0) cout << "、";
            cout << a.genres[i];
        }
        cout << endl;
        cout << "活跃年份:" << a.startingYear << " - " << a.endingYear << endl;
        cout << "专辑数量:" << a.numOfTracks << endl;
        cout << "专辑列表:" << endl;
        for (size_t i=0; i<a.disc.trackTitle.size(); i++) {
            cout << "  " << a.disc.trackTitle[i] << " (" << a.disc.trackYear[i] << ")" << endl;
        }
        cout << "------------------------" << endl;
    }
}

后续的搜索功能直接遍历allArtists向量匹配对应条件即可,不需要再操作文件。

内容的提问来源于stack exchange,提问作者isoscelesTriangle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:36:04