重载>>运算符解析TXT文件仅能读取一个对象的问题排查
问题:重载>>运算符读取多个ExercisePlan对象失败
我在完成学校作业时,通过重载>>运算符解析文本文件并将内容赋值给ExercisePlan类,但目前仅能读取.txt文件中的第一个对象,后续对象读取完全失败——调试发现读取第二个计划时,文件读取直接停止。
运算符重载实现
std::istream &operator>>(std::istream &is, ExercisePlan &plan) { std::string name; int steps; std::string date; std::getline(is, name); is >> steps; is.ignore(); std::getline(is >> std::ws, date); plan.setPlanName(name); plan.setGoalSteps(steps); plan.setDate(date); return is; }
调用重载运算符的代码
loadDailyPlan函数
template<typename T> void FitnessAppWrapper::loadDailyPlan(std::fstream &fileStream, T& plan) { fileStream >> plan; }
loadWeeklyPlan函数
void FitnessAppWrapper::loadWeeklyPlan(std::fstream &fileStream, DietPlan *weeklyPlan) { for(int i = 0; i < 7; i++){ //loadDailyPlan(fileStream,weeklyPlan[i]); fileStream >> weeklyPlan[i]; } }
文本文件ExercisePlans.txt内容
Morning Walk 5000 02/22/2024 Gym Session 6000 02/23/2024 Cycling 5500 02/22/2024 Swimming 7000 02/25/2024 Running 8000 02/26/2024 Yoga 4500 02/27/2024 Hiking 7000 02/28/2024
解析结果(display函数输出)
|Exercise Plan: Morning Walk |Date: 02/22/2024 |Goal: 5000 Steps |Exercise Plan: |Date: |Goal: 0 Steps |Exercise Plan: |Date: |Goal: 0 Steps |Exercise Plan: |Date: |Goal: 0 Steps |Exercise Plan: |Date: |Goal: 0 Steps |Exercise Plan: |Date: |Goal: 0 Steps |Exercise Plan: |Date: |Goal: 0 Steps
附display函数实现
std::ostream &operator<<(std::ostream &os, const ExercisePlan &plan) { os << "|Exercise Plan: " << plan.getPlanName() << "\n"; os << "|Date: " << plan.getDate() << "\n"; os << "|Goal: " << plan.getGoalSteps() << " Steps\n"; /*os << plan.getPlanName() << "\n"; os << plan.getDate() << "\n"; os << plan.getGoalSteps() << "\n";*/ return os; }
附ExercisePlan类定义
class ExercisePlan { private: int goalSteps; std::string planName; std::string date; public: // ## SETTERS AND GETTERS int getGoalSteps() const; void setGoalSteps(int goalSteps); const string &getPlanName() const; void setPlanName(const string &planName); const string &getDate() const; void setDate(const string &date); // ## CONSTRUCTORS ExercisePlan(); ExercisePlan(int steps, const std::string& name, const std::string& date); ExercisePlan(const ExercisePlan& other); // ## DESTRUCTOR ~ExercisePlan(); // ## OTHER FUNCTIONS void editGoal(); friend std::ostream& operator<<(std::ostream& os, const ExercisePlan& plan); friend std::istream& operator>>(std::istream& is, ExercisePlan& plan); friend std::fstream& operator<<(std::fstream &fileStream, ExercisePlan &plan); };
问题原因与修复方法
问题根源
读取完第一个计划后,文件指针停留在第一个计划日期行后的空行处,当前的>>运算符实现未处理这个空行分隔符。第二次读取时,getline直接读到空字符串,后续is >> steps读取失败并设置了流的错误状态,导致所有后续读取操作直接跳过。
修复后的>>运算符实现
std::istream &operator>>(std::istream &is, ExercisePlan &plan) { std::string name; int steps; std::string date; std::string blankLine; // 跳过计划之间的空行分隔符 while (is && std::getline(is, blankLine) && blankLine.empty()); if (!is) return is; // 流已结束则直接返回 // 用读到的非空行作为计划名称 name = blankLine; // 读取步数,失败则返回 if (!(is >> steps)) return is; is.ignore(); // 忽略步数后的换行符 // 读取日期 std::getline(is >> std::ws, date); plan.setPlanName(name); plan.setGoalSteps(steps); plan.setDate(date); return is; }
额外注意点
loadWeeklyPlan函数的参数是DietPlan *weeklyPlan,但实际要读取的是ExercisePlan对象,这里存在类型不匹配的笔误,需修改为ExercisePlan *weeklyPlan。
内容的提问来源于stack exchange,提问作者sangregoriokimpo
相关产品推荐
相关产品推荐

