2015-08-03 6 views
0

У меня есть проблема с импортированием простого текста (это упражнение книги). Я могу экспортировать значение вектора настраиваемого типа Point, но я не могу их прочитать и сохранить в другом векторе. Я много раз пытался понять, что может быть причиной, и я увидел, что в цикле while программа строит вектор, но когда дело доходит до конца, оно дает мне run_time_error. Думаю, он не распознает конец файла. Это мои файлы:Ошибка при импорте файла txt

Заголовок файла:

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); 
    } 
} 

Главный файл:

// Work with external files.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include "std_lib_facilities.h" 
#include "wfile.h" 


int main() 
{ 
    Point p; 
    vector<Point> original_points; 
    vector<Point> processed_points; 

    cout << "Please enter 7 pairs of numbers: " << endl; 

    for (int i = 0; i <= 6; ++i) 
    { 
     cout << "#" << i + 1 << " pair: "; 
     cin >> p; 

     original_points.push_back(p); 
    } 

    p.print_all(original_points); 

    cout << original_points << endl; 

    p.import_all(processed_points); 

    cout << processed_points << endl; 

    keep_window_open(); 

    return 0; 
} 
+0

Как выглядит ваш тип точки? structs и classes по сути не поддерживают операции вставки/извлечения потока (<< and >>, соответственно). В методе print_all вы вставляете значения x и y в поток. чтобы использовать >> для чтения значений точки x и y, вам нужно будет перегрузить оператор >> в типе точки или сначала прочитать значения x и y отдельно, а затем сохранить их в точке – youngmit

+0

. Вы заявили, что получить ошибку времени выполнения. Но сообщение об ошибке должно быть больше. В какой строке это происходит? Каков полный текст ошибки? – abelenky

+0

@ youngmit Да я перегрузил необходимых операторов. Я предпочел не помещать их в сообщение, пытаясь не быть грязным. –

ответ

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>.

+0

Спасибо, это сработало! У меня есть другой вопрос относительно обработки ошибок. Чтобы обрабатывать ошибки, я должен создать функцию, например. 'bool is_point (const Point & p) {...}' и пусть он проверяет правильность ввода в 'int main()' right? Это ты имел в виду? –

+1

@ LeonardoUrbano Я бы просто проверил, чтобы убедиться, что поток извлечения работает. Я отредактировал свой ответ, чтобы указать, как проверять точки, которые вводятся – NathanOliver

+0

Спасибо, ты действительно помог мне! Это очень полезно –

Смежные вопросы