我有一个关于导入简单文本的问题(这是一本书的练习)。我能够导出自定义类型Text
的向量值,但我无法将它们读回并将它们存储在另一个向量中。我已经多次尝试了解哪个可能是原因而且我在Point
循环中看到程序构建了向量但是当它结束时它给了我一个while
。我想它无法识别文件的结尾。这些是我的文件:
标题文件:
run_time_error
源文件:
class Point
{
private:
int x, y;
public:
Point();
Point(int x1, int y1);
int get_x() const { return x; }
int get_y() const { return y; }
void print_all(const vector<Point>& pv);
void import_all(vector<Point>& pv);
Point operator=(const Point& p);
};
istream& operator>>(istream& is, Point& p);
ostream& operator<<(ostream& os, const Point& p);
ostream& operator<<(ostream& os, const vector<Point>& p);
主档案:
#include "stdafx.h"
#include "std_lib_facilities.h"
#include "wfile.h"
Point::Point()
: x{ 0 }, y{ 0 } {}
Point::Point(int x1, int y1)
: x{ x1 }, y{ y1 } {}
Point Point::operator=(const Point& p)
{
x = p.get_x(); y = p.get_y();
return *this;
}
ostream& operator<<(ostream& os, const Point& p)
{
return os << '(' << p.get_x() << ','
<< p.get_y() << ')' << endl;
}
ostream& operator<<(ostream& os, const vector<Point>& p)
{
for (int i = 0; i < p.size(); ++i)
{
cout << i + 1 << ")" << " "
<< "X: " << p[i].get_x() << " " << "Y: " << p[i].get_y() << endl;
}
return os;
}
istream& operator>>(istream& is, Point& p)
{
int x, y;
is >> x >> y;
if (!is)
{
error("Bad input.");
is.clear(ios::failbit);
is.unget();
return is;
};
p = Point(x, y);
return is;
}
void Point::print_all(const vector<Point>& pv)
{
cout << "Please enter file output name: " << endl;
string oname;
cin >> oname;
ofstream ost{ oname };
if (!ost) error("Can't open output file.", oname);
for (int i = 0; i < pv.size(); ++i)
{
ost << pv[i].get_x() << " " << pv[i].get_y() << endl;
}
}
void Point::import_all(vector<Point>& pv)
{
cout << "Please enter file input name: " << endl;
string iname;
cin >> iname;
ifstream ist{ iname };
if (!ist) error("Can't read file, ", iname);
while (true)
{
Point p;
if (!(ist >> p)) break;
pv.push_back(p);
}
}
答案 0 :(得分:2)
这可能无法解决您的问题,但您的代码存在一些问题。当您对提取运算符进行重载时,您不应该清除过载中的任何错误,而是将它们从函数中传出。有了这个,operator >>
应该是:
istream& operator>>(istream& is, Point& p)
{
is >> p.x >> p.y;
return is;
}
现在,如果流提取出现问题,istream
对象将处于错误状态,您可以在调用代码中处理它。
下一个问题是您从文件中读取的方式。从文件中读取时,应使用流提取操作来控制循环。这样做的好处是,如果出现错误,它将不再循环,一旦到达文件末尾,它将不再循环。因此,您需要将import_all()
更改为:
void Point::import_all(vector<Point>& pv)
{
cout << "Please enter file input name: " << endl;
string iname;
cin >> iname;
ifstream ist{ iname };
if (!ist) error("Can't read file, ", iname);
Point p;
while (ist >> p)
{
pv.push_back(p);
}
}
现在第三,如果从流中提取Point
时出错,您可以检查以确保在我们使用该点之前没有读取错误。为此,您可以将循环更改为:
for (int i = 0; i <= 6; ++i)
{
cout << "#" << i + 1 << " pair: ";
cin >> p;
if(!cin) // cin is in an error state
{
cout << "invalid point entered. Please enter a valid point." << endl;
cin.clear(); // clear the error flags
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // empty stream of bad input
i--; // decrement i so we loop back to asking for the same input
}
else // extraction worked so store the point
original_points.push_back(p);
}
要使用std::numeric_limits<std::streamsize>::max()
,您需要#include <limits>
。