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
相关产品推荐
相关产品推荐

