导入文件txt时出错

时间:2015-08-03 15:43:04

标签: c++

我有一个关于导入简单文本的问题(这是一本书的练习)。我能够导出自定义类型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);
    }
}

1 个答案:

答案 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>