C ++ - чтение файла .csv в векторы, пропуская первую строку и определенные столбцы - PullRequest
0 голосов
/ 06 декабря 2018

Я пытаюсь прочитать в CSV-файле, который выглядит следующим образом:

Name,Place,Age,x,y
A,X,1,50,100
B,Y,2,-90,20
C,Z,3,0.4,80
...

За исключением 100 строк данных (плюс заголовок).

Я хотел бычтобы прочитать в столбцах Имя, Возраст, x и y и поместить их в вектор, который выглядит следующим образом:

Name = [Age, x, y]

и сделать это для всех 100 строк (таким образом, 100 векторов).

Я пытался найти помощь по форуму, но лучшая помощь, которую я мог получить, была от c ++ Пропустить первую строку файла csv , который я немного изменил, чтобы напечатать Age, x, y.

ifstream data("data.csv");
    if (!data.is_open())
    {
        exit(EXIT_FAILURE);
    }
    string str;
    getline(data, str); // skip the first line
    while (getline(data, str))
    {
        istringstream iss(str);
        string token;
        while (getline(iss, token, ','))
        {
            double Age_x_y = atof(token.c_str());

            if (Age_x_y != 0) {
                cout << Age_x_y << " ";
            }
            cout << endl;
        }
    }

Это хорошо, если бы это было все, что я хотел вывести, но я считаю, что все данные просто хранятся как двойные.Мне нужны данные, хранящиеся в векторе (или что-то вроде структуры), чтобы я мог манипулировать записями.Например, я хотел бы определить x + y для каждого Имени.

Как мне извлечь данные таким образом?

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 06 декабря 2018

Ваш анализ CSV - это хорошо, но будьте осторожны, чтобы вы не предоставили никаких данных, если в полях есть запятые.Некоторые форматировщики CSV допускают, чтобы поле содержало запятую, если поле заключено в двойные кавычки, например.

Вы можете создать структуру, которая представляет (более или менее) одну строку в вашем файле CSV.

struct Record
{
    std::string name;
    std::string place;
    int age;
    double x;
    double y;
};

Теперь вы можете разобрать каждую строку в объекте Record (выбрать подходящее имя для структуры), а затем поместить каждый Record в вектор.Обязательно включите <string> и <vector>.

std::vector<Record> my_records;
while (getline(data, str))
{
    Record record;
    istringstream iss(str);
    string token;

    getline(iss, record.name, ',');
    getline(iss, record.place, ',');

    // use atoi(token.c_str()) if you don't have std::stoi from C++11
    getline(iss, token, ',');
    record.age = std::stoi(token);

    // use atof(token.c_str()) if you don't have std::stod from C++11
    getline(iss, token, ',');
    record.x = std::stod(token);

    getline(iss, token, ',');
    record.y = std::stod(token);

    my_records.push_back(record);
}

// loop through the vector, summing every possible
// combination of x values. The outer loop goes from
// index 0 to the second-to-last index, while the inner
// loop goes from the current outer loop counter to the
// last index.

// Note that this is O(n^2) complexity (even with a
// diminishing inner loop). Increasing the number of
// records can have a very noticeable effect on running
// time.
for (size_t i = 0; i < my_records.size() - 1; i++)
{
    for (size_t j = i + 1; j < m_records.size(); j++)
    {
        std::cout << my_records[i].name << ".x + ";
        std::cout << my_records[j].name << ".x = ";
        std::cout << (my_records[i].x + my_records[j].x) << std::endl;
    }
}

. Вы также можете использовать my_records[i].x + my_records[i].y, если хотите вывести сумму этих значений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...