这是学校作业。我正在重载>>,以便我可以解析文本文件并将其分配给一个类。
由于某种原因,我只能从 .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;
}
这是我调用运算符重载器的地方:
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];
}
}
这是我的文本文件,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
这是解析器读取的内容(我有一个显示信息的显示函数):
|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
我在调试器中查看了代码,我发现当我尝试读取第二个练习计划时,它只是停止读取文件?
如果需要的话,这是我的显示功能:
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;
}
如果需要,这是我的课程:
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);
};
我使用函数重载和运算符重载的原因是因为我有一个与ExercisePlan类似的类,称为DietPlan,并且有一个类似的.txt文件,我也需要解析它。
这是您问题的简化代码。我猜您打算跳过每个数据之间的空格,但您在提取数据完成之前调用了
ifs.ignore()
。
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream ifs("ExercisePlans.txt");
for (int i = 0; i < 7; ++i) {
std::string name;
int steps;
std::string date;
std::getline(ifs, name);
ifs >> steps;
ifs.ignore(); // WRONG. should be called after the following line
std::getline(ifs >> std::ws, date);
std::cout << "status of ifs: " << (ifs.good() ? "GOOD" : "ERR") << "\n";
std::cout << name << " " << steps << " " << date << "\n\n";
}
return 0;
}
我测试了切换
std::getline(ifs>>std::ws,date)
并且 ifs.ignore()
有效。
此外,您还可以通过调用
ifs.good()
、ifs.fail()
或ifs.bad()
来检查流操作是否成功。通过我输入的上述代码看看流的状态如何变化。
文件中每组信息之间有一个空行。
std::getline(is, name);
这会读取该空行,然后您尝试将名称读取为
int
并且流会进入失败状态。
您需要考虑输入流中每次提取之间的空行。