Как сопоставить строковые значения из двух строковых векторов во вложенном цикле

Я пытаюсь найти индексы для определенных значений заголовка в файле CSV, чтобы затем я мог использовать их для извлечения данных в этих позициях в остальной части файла. Я добавляю значения заголовка в map<std::string, int> так что я могу сохранить индексы.

У меня был рабочий код, пока я не заметил, что если заголовок является последним значением в строке, он не совпадает. Последняя строка заголовка пуста внутри моего вложенного цикла, но не во внешнем цикле.

const int columnCount = 2;
std::string columns[columnCount] = { "column1", "column2" };

map<std::string, int> columnMap;

std::vector<std::string> cols(columns, columns + columnCount);
std::vector<std::string> cells;

boost::tokenizer<boost::escaped_list_separator<char> > tok(header_row);
cells.assign(tok.begin(), tok.end());

std::vector<std::string>::iterator iter_cells;
std::vector<std::string>::iterator iter_cols;

for (iter_cells = cells.begin(); iter_cells != cells.end(); ++iter_cells) {
std::string cell = *iter_cells;
for(iter_cols = cols.begin(); iter_cols != cols.end(); ++iter_cols) {
std::string col = *iter_cols;
cout << cell << "=" << col;
if(col.compare(cell) == 0) {
cout << " MATCH" << endl;
columnMap.insert(std::make_pair(*iter_cols,iter_cells-cells.begin()));
break;
}
cout << endl;
}
}

Где tok(row) является эквивалентом tok("column0,column1,column2") Я получаю этот вывод;

column0=column1
column0=column2
column1=column1 MATCH
=column1
=column2

Тогда как если это tok("column0,column1,column2,column3") Я получил;

column0=column1
column0=column2
column1=column1 MATCH
column2=column1
column2=column2 MATCH
=column1
=column2

Когда я cout << cell во внешнем цикле значение отображается правильно.

Почему я теряю ценность cell во внутреннем цикле?

РЕДАКТИРОВАТЬ

Код в github и тестовые файлы скомпилированы с;

gcc parse_csv.cpp -o parse_csv -lboost_filesystem -lmysqlpp

и выполнен с

./parse_csv /home/dave/SO_Q/

Я получаю этот вывод;

Process File: /home/dave/SO_Q/test_2.csv
metTime
metTime=metTime MATCH
Ta
=metTime
=Ta
=Ua
=Th
Process File: /home/dave/SO_Q/test_1.csv
DATE_TIME_UTC
DATE_TIME_UTC=metTime
DATE_TIME_UTC=Ta
DATE_TIME_UTC=Ua
DATE_TIME_UTC=Th
Ta
Ta=metTime
Ta=Ta MATCH
metTime
=metTime
=TaTime
=UaTime
=ThTime

1

Решение

Не уверен, как вы заполняете переменную «header_row», но приведенный ниже код работает для меня, я получаю этот вывод

column0 = столбец1

column0 = столбец2

column1 = column1 MATCH

столбец2 = столбец1

column2 = column2 MATCH

Столбец3 = столбец1

Столбец3 = столбец2

#include  <boost/tokenizer.hpp>
#include <iostream>
#include <fstream>
#include <map>

using namespace std;int main()
{
//create csv
ofstream csvFile ("data.csv");
std::string row = "column0,column1,column2,column3";

csvFile << row;

csvFile.close();

const int columnCount = 2;
std::string columns[columnCount] = { "column1", "column2" };

map<std::string, int> columnMap;

std::vector<std::string> cols(columns, columns + columnCount);
std::vector<std::string> cells;

//open csv file
std::string header_row;
ifstream csvRead("data.csv");
assert(csvRead.is_open());
getline(csvRead,header_row);

boost::tokenizer<boost::escaped_list_separator<char> > tok(header_row);
cells.assign(tok.begin(), tok.end());
//close file
csvRead.close();

std::vector<std::string>::iterator iter_cells;
std::vector<std::string>::iterator iter_cols;

//original loops as provided in question
for (iter_cells = cells.begin(); iter_cells != cells.end(); ++iter_cells) {
std::string cell = *iter_cells;
for(iter_cols = cols.begin(); iter_cols != cols.end(); ++iter_cols) {
std::string col = *iter_cols;
cout << cell << "=" << col;
if(col.compare(cell) == 0) {
cout << " MATCH" << endl;
columnMap.insert(std::make_pair(*iter_cols,iter_cells-cells.begin()));
break;
}
cout << endl;
}
}

}
0

Другие решения

Проблема была с вводом для строки заголовка. Он содержал разрыв строки в конце, который не соответствовал элементам в массиве. Устранение разрыва строки устранило проблему.

Я работал на ПК с Windows, а затем перенес файл на компьютер с ОС Cent для запуска кода, и разница в окончаниях строк между двумя платформами и стала причиной проблемы.

Используя это как оператор отладки cout << cell покажет строку и проигнорирует разрыв строки. Используя что-то вроде cout << cell << " CELL" не показывал строку из-за разрыва строки.

Теперь я добавил это в мой код, чтобы поймать разницу в переводе строки

// remove possible windows line ending so last item matches
if(header_row[header_row.length()-1] == '\r') {
header_row.erase(header_row.size()-1);
}
0

По вопросам рекламы [email protected]