Анализ файлов .csv со структурой CR LF EOL

Я пытаюсь проанализировать файл CSV, и getline() читает весь файл как одну строку. Предполагая, что getline() не получает ожидаемого результата, я безуспешно пробовал \r, \n, \n\r, \r\n и \0 в качестве аргументов.

Я взглянул на символы EOL и увидел CR, а затем LF. getline() просто игнорирует это или я что-то упускаю? Кроме того, что исправить здесь?

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

vector<vector<string>> Parse::parseCSV(string file)
{
    // input fstream instance
    ifstream inFile;
    inFile.open(file);

    // check for error
    if (inFile.fail()) { cerr << "Cannot open file" << endl; exit(1); }

    vector<vector<string>> data;
    string line;

    while (getline(inFile, line))
    {
        stringstream inputLine(line);
        char delimeter = ',';
        string word;
        vector<string> brokenLine;
        while (getline(inputLine, word, delimeter)) {
            word.erase(remove(word.begin(), word.end(), ' '), word.end());      // remove all white spaces
            brokenLine.push_back(word);
        }
        data.push_back(brokenLine);
    }

    inFile.close();

    return data;

};

Вот шестнадцатеричный дамп. Я не уверен, что именно это показывает.

0000000 55 4e 49 58 20 54 49 4d 45 2c 54 49 4d 45 2c 4c
0000010 41 54 2c 4c 4f 4e 47 2c 41 4c 54 2c 44 49 53 54
0000020 2c 48 52 2c 43 41 44 2c 54 45 4d 50 2c 50 4f 57
0000030 45 52 0d 31 34 32 34 31 30 35 38 30 38 2c 32 30
0000040 31 35 2d 30 32 2d 31 36 54 31 36 3a 35 36 3a 34
0000050 38 5a 2c 34 33 2e 38 39 36 34 2c 31 30 2e 32 32
0000060 34 34 34 2c 30 2e 38 37 2c 30 2c 30 2c 30 2c 4e
0000070 6f 20 44 61 74 61 2c 4e 6f 20 44 61 74 61 0d 31
0000080 34 32 34 31 30 35 38 38 35 2c 32 30 31 35 2d 30
0000090 32 2d 31 36 54 31 36 3a 35 38 3a 30 35 5a 2c 34
00000a0 33 2e 39 30 31 33 35 2c 31 30 2e 32 32 30 34 31
00000b0 2c 31 2e 30 32 2c 30 2e 36 33 39 2c 30 2c 30 2c
00000c0 4e 6f 20 44 61 74 61 2c 4e 6f 20 44 61 74 61 0d
00000d0 31 34 32 34 31 30 35 38 38 38 2c 32 30 31 35 2d
00000e0 30 32 2d 31 36 54 31 36 3a 35 38 3a 30 38 5a 2c
00000f0 34 33 2e 39 30 31 34 38 2c 31 30 2e 32 32 30 31
0000100

Первые две строки файла

UNIX TIME,TIME,LAT,LONG,ALT,DIST,HR,CAD,TEMP,POWER
1424105808,2015-02-16T16:56:48Z,43.8964,10.22444,0.87,0,0,0,No Data,No Data

ОБНОВЛЕНИЕ Похоже, это было \r. Я не уверен, почему это не сработало раньше, но я узнал несколько вещей во время изучения. Спасибо за помощь, ребята!


person Will Luce    schedule 01.03.2015    source источник
comment
Сделайте любой ответ на этот вопрос, Как я могу читать и анализировать CSV-файлы на C++?, помочь вообще?   -  person WhozCraig    schedule 01.03.2015
comment
Я прочитал их, и хотя они касаются того, о чем я говорю, я не понимаю, что с этим делать.   -  person Will Luce    schedule 01.03.2015
comment
Предполагая, что ваш файл так же прост, как описано. ваш код выглядит так, как будто он должен быть правильным. Итак, в итоге вы говорите, что while (getline(inFile, line)) бьет однажды и проглатывает все? На какой платформе это работает?   -  person WhozCraig    schedule 01.03.2015
comment
Я на Mac работаю в Xcode. Функция запускается, но никогда не разрывает строки и загружает весь файл в одну строку. Файл на самом деле ›700 строк.   -  person Will Luce    schedule 01.03.2015
comment
Был ли файл создан и на вашем Mac? Мне действительно любопытно, как будет выглядеть обход этого файла по символам, потому что std::getline должен правильно извлекать этот файл для каждой строки, если у вас нет шатких окончаний строк. можете ли вы обновить свой вопрос, включив в него hexdump filename из первых 200 или около того символов (все, что должно быть окончанием строки)?   -  person WhozCraig    schedule 01.03.2015
comment
Нет, он был конвертирован сторонним программным обеспечением. Я собираюсь добавить картину того, что я получил, когда я сломал его.   -  person Will Luce    schedule 01.03.2015
comment
Пожалуйста, без картинок, если это возможно, и особенно, если это можно продемонстрировать с помощью шестнадцатеричного дампа в виде текста. Просто откройте консоль и вставьте hexdump -n 256 filename в вопрос, так как список источников, вероятно, будет достаточно хорошим, при условии, что первая строка не длиннее 256 байтов. Будет выглядеть примерно так и будет хорошим дополнением к вашему вопросу. Фактический текст первых нескольких строк для сопровождения тоже будет хорош.   -  person WhozCraig    schedule 01.03.2015
comment
Спасибо, наконец-то включил первые две строки реального текста из файла. Кажется очень странным, что цикл while срабатывает один раз. Вы подтвердили, что у data есть одна запись, верно? (знаю, кажется излишним вопрос, но должен спросить). Судя по этому дампу, разделитель 0x0D или '\r' только. И вы говорите, что пытались изменить внешний getline на std::getline(inFile, line, '\r')?   -  person WhozCraig    schedule 01.03.2015
comment
Ну вот. Данные — это только результат функции. В файле не указано.   -  person Will Luce    schedule 01.03.2015


Ответы (2)


Простым решением было бы написать свой собственный getline
Например, тот, который игнорирует любую комбинацию \n,\r
в начале строки, а также прерывает любую комбинацию.
Это будет работать на любой платформе, но не сохранит пустые строки.

После просмотра шестнадцатеричного дампа разделитель 0d (\r)

person sp2danny    schedule 01.03.2015

Вы пытались изменить порядок \r\n на \n\r?

person Shay Nehmad    schedule 01.03.2015
comment
Да, я их поменял. Оказывается, getline() принимает только один символ в качестве разделителя. Таким образом, ни один из них не является допустимым, и оба вызывают ошибку. - person Will Luce; 01.03.2015
comment
В Getline есть разделитель, верно? Может быть, использовать это? - person Shay Nehmad; 01.03.2015
comment
Параметр разделителя принимает только один символ. - person Will Luce; 01.03.2015
comment
Это не так. В вопросе перечислены комбинации, которые я пробовал. - person Will Luce; 01.03.2015
comment
\n\r не является разделителем строк ни в одной из когда-либо построенных компьютерных систем. Предложение бесполезное. Подробнее см. здесь. - person user207421; 20.04.2015