This is for a school assignment. I am overloading >> so that I can parse a text file and assign it to a class.
For some reason, I can only read one object from the .txt file.
Here is my attempt at operator overloading:
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;
}
Here is where I call my operator overloader:
template<typename T>
void FitnessAppWrapper::loadDailyPlan(std::fstream &fileStream, T& plan) {
fileStream >> plan;
}
void FitnessAppWrapper::loadWeeklyPlan(std::fstream &fileStream, DietPlan *weeklyPlan) {
for(int i = 0; i < 7; i++){
//loadDailyPlan(fileStream,weeklyPlan[i]);
fileStream >> weeklyPlan[i];
}
}
Here is my text file, ExercisePlans.txt
Morning Walk
5000
02/22/2024
Gym Session
6000
02/23/2024
Cycling
5500
02/24/2024
Swimming
7000
02/25/2024
Running
8000
02/26/2024
Yoga
4500
02/27/2024
Hiking
7000
02/28/2024
Here is what the parser reads (I have a display function that displays the information):
|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
I've went through the code in debugger, and I found that when I try to read the second exercise plan, it just stops reading the file?
If needed, here is my display function:
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;
}
If needed, here is my class:
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);
};
The reason why I am using function overloading and operator overloading is because I have a similar class to ExercisePlan, called DietPlan, with a similar .txt file that I also need to parse.
This is a simplified code from your question. I guess you intended to skip white spaces between each data, but you're calling
ifs.ignore()before extracting one is completed.I tested switching
std::getline(ifs>>std::ws,date)andifs.ignore()worked.In addition, you can check if your stream operations are successful by calling
ifs.good(),ifs.fail()orifs.bad(). See how the status of stream changed with the above code I put.