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

重载>>运算符解析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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:45:08