类聚合场景下:如何实现全局函数readPlayersFromFile读取玩家数据至对象数组
修正并完善
readPlayersFromFile函数实现 需求说明
需要实现全局函数readPlayersFromFile(ifstream&),将players.txt中的玩家信息读取到Player对象数组中:
- 文件首行记录玩家总数
- 每个玩家的信息依次为:姓名(可能包含空格)、出生年份、身高、国家队进球数、国籍,每项占一行
文件示例:
100 Mohamed Salah 1992 173 48 Egyptian //////其余玩家信息格式同上,直至第100位//////
原代码存在的问题
- 使用getter函数(如
getName())作为赋值目标:getter通常返回值类型,无法作为左值接收输入,需改用setter函数或直接访问成员变量 - 读取姓名时用
>>会截断空格:姓名可能包含空格(如Mohamed Salah),需用getline读取整行 - 读取玩家总数后未处理换行符:
in >> num会留下换行符在输入缓冲区,后续getline会读取空行,需先忽略 - 循环条件
!in.eof()易导致多读一次:已知玩家总数,应通过循环次数精确控制读取 - 函数返回
0:应返回创建的Player数组指针 - 代码语法错误:
in>>p[i].getNationality()末尾缺少分号
修正后的代码
假设Player类提供以下setter方法:
class Player { private: std::string name; int yearOfBirth; int height; int internationalGoals; std::string nationality; public: void setName(const std::string& n) { name = n; } void setYearOfBirth(int y) { yearOfBirth = y; } void setHeight(int h) { height = h; } void setInternationalGoals(int g) { internationalGoals = g; } void setNationality(const std::string& nat) { nationality = nat; } };
修正后的读取函数:
#include <fstream> #include <string> #include <limits> Player* readPlayersFromFile(std::ifstream& in) { int num; // 读取玩家总数,失败则返回空指针 if (!(in >> num)) { return nullptr; } // 忽略总数后的换行符,避免影响后续getline读取 in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 创建Player对象数组 Player* players = new Player[num]; for (int i = 0; i < num; ++i) { std::string name; // 读取姓名(整行) if (!std::getline(in, name)) { delete[] players; return nullptr; } players[i].setName(name); int year; if (!(in >> year)) { delete[] players; return nullptr; } players[i].setYearOfBirth(year); in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); int height; if (!(in >> height)) { delete[] players; return nullptr; } players[i].setHeight(height); in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); int goals; if (!(in >> goals)) { delete[] players; return nullptr; } players[i].setInternationalGoals(goals); in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); std::string nationality; if (!std::getline(in, nationality)) { delete[] players; return nullptr; } players[i].setNationality(nationality); } return players; }
关键说明
- 处理输入缓冲区换行符:每次用
>>读取数值后,调用ignore跳过换行符,确保下一次getline读取到正确内容 - 错误处理:每次读取操作后检查是否成功,失败则释放已分配内存,避免内存泄漏
- 精确控制循环:通过玩家总数
num控制循环次数,避免eof()导致的多读问题 - 读取带空格字符串:用
getline读取姓名和国籍,确保完整获取包含空格的内容
内容的提问来源于stack exchange,提问作者Noureen mohey
相关产品推荐
相关产品推荐

