Чтение точек из потока, состоящего только из одной строки

У меня есть файл, который сначала сообщает мне, сколько точек я буду читать в следующей строке. Итак, например, мой файл выглядит так:

7
a,b c,d e,f g,h, i,j k,l m,n

Итак, я знаю, что следующая строка после 7 - это 7 пар целых чисел, разделенных запятой, и каждая пара разделена пробелом.

Что я хочу: иметь вектор из 7 элементов Point.

У меня есть класс Point:

class Point {
public:
    int x;
    int y;
    bool operator==(const Point q){
        return (q.x == this->x && q.y == this->y);
    }
};

Поэтому, когда я читаю этот файл, я хотел бы иметь вектор V, где:

V[0].x = a
V[0].y = b
V[1].x = c
V[1].y = d

и так далее.

Я могу прочитать 7 в порядке, но как мне прочитать каждую из 7 пар целых чисел по отдельности? Мне это нужно, потому что я собираюсь хранить (a,b) (c,d)... в векторе.

Есть не только 2 балла. Первая строка файла сообщает мне, сколько точек я собираюсь сохранить.

Они не читаются из стандартного ввода.

Они читаются из файла.

Я пытался использовать sscanf, но я думаю, что это только для тех случаев, когда у вас есть несколько строк с этой информацией, и я не хотел бы изменять свой формат.

Это то, что у меня есть до сих пор:

void process_file(string filename){
    ifstream thracklefile;
    string line;
    int set_size;
    thracklefile.open(filename);

    getline(thracklefile,line); //store set size.
    set_size = stoi(line);

    //Store points in following line
    points.clear();
    points.resize(set_size);
    getline(thracklefile,line); //store the points.
    }

Я не хочу игнорировать запятые, каждая запятая является частью информации, которую я хочу сохранить для каждой точки.


person David Merinos    schedule 14.01.2019    source источник
comment
Спасибо за ваше время, однако это не то, что я хочу. Я обновляю вопрос, поскольку у меня уже есть отрицательный голос без объяснения причин.   -  person David Merinos    schedule 15.01.2019
comment
Я обновил вопрос.   -  person David Merinos    schedule 15.01.2019
comment
@DavidMerinos Вы действительно хотите игнорировать запятые. Вам нужно char comma; for (int i = 0; i < set_size; ++i) thracklefile >> V[i].x >> comma >> V[i].y;   -  person NathanOliver    schedule 15.01.2019
comment
Но я сохранил строку, где информация о точке находится в переменной line, которая является строкой. Могу ли я сделать это со строками тоже?   -  person David Merinos    schedule 15.01.2019
comment
Конечно, поместите строку в поток строк: std::getline(thracklefile, line); std::istringstream ss(line); char comma; int x, y; while( ss >> x >> comma >> y ) { ... }   -  person Ted Lyngmo    schedule 15.01.2019
comment
Я не хочу игнорировать запятые Вы хотите сохранить запятые в ваших векторах? Я думаю, что ответ на этот вопрос отрицательный, поэтому вы действительно хотите их игнорировать. Они служат только в качестве знаков препинания во входных данных, чтобы сигнализировать о значении остальных данных.   -  person Code-Apprentice    schedule 15.01.2019
comment
Спасибо @TedLyngmo, если бы я мог, я бы пометил ваш ответ как принятый, однако мой вопрос был помечен как дубликат, хотя это явно не так.   -  person David Merinos    schedule 15.01.2019
comment
@Code-Apprentice Я должен был сказать это, потому что они использовали этот факт, чтобы пометить мой вопрос как дубликат.   -  person David Merinos    schedule 15.01.2019
comment
У меня был полный рабочий пример, готовый к публикации, но я опоздал всего на одну секунду :-)   -  person Ted Lyngmo    schedule 15.01.2019
comment
@DavidMerinos Заявление о том, что вы не хотите игнорировать запятые, по-прежнему не объясняет, почему ваш вопрос не является дубликатом связанного вопроса.   -  person Code-Apprentice    schedule 15.01.2019
comment
Чувак, только что прочитал вопрос, я его отредактировал. Тед понял, конечно, я не хочу хранить запятые, но это не значит, что мой вопрос сводится к их игнорированию. Это не дубликат вопроса, отмеченного как таковой.   -  person David Merinos    schedule 15.01.2019
comment
И указанный вопрос также не отвечает на мой вопрос. Хорошего дня, сэр.   -  person David Merinos    schedule 15.01.2019


Ответы (1)


Я думаю, что большая часть обсуждения в комментариях касается семантики. Рекомендуется «игнорировать» запятые, но вы не можете этого сделать, так как они есть в файле. Возможно, лучшим термином будет «отбросить». Слово «игнорировать» используется, поскольку существует функция C++ iostream ignore.

Есть много способов справиться с этим. Один из вариантов — переопределить операторы вставки/извлечения потока:

class Point {
public:
    int x;
    int y;

    // Don't really need this as members are public, but
    // in case you change that in the future....
    friend istream& operator>>(istream& in, Point& p);
    friend ostream& operator<<(ostream& out, const Point& p);
};

istream& operator>>(istream& in, Point& p)
{
    char separator;
    // Try to read <int><char><int>
    in >> p.x >> separator >> p.y;
    // The stream may be in an error state here. That
    // is ok. Let the caller handle that
    // Also note that we discard (ignore) "separator"
    return in;
}
ostream& operator<<(ostream& out, const Point& p)
{
    out << p.x << ',' << p.y;
    return out;
}

int main() {
    int num_points;
    std::cin >> num_points;
    Point p;
    for (int i = 0; i < num_points; i++) {
        if (!(std::cin >> p)) {
            // There was an error
            std::cout << "File format error!" << std::endl;
            break;
        }
        std::cout << p << std::endl;
    }

    return 0;
}

В примере используется cin, но должен работать любой поток, включая ifstream.

person Johnny Mopp    schedule 15.01.2019