我正在尝试在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
的值?
修改
Code in 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
答案 0 :(得分:0)
不确定你是如何填充变量“header_row”但是下面的代码对我有效我得到了这个输出
column0 =列1
column0 = column2的
column1 = column1 MATCH
列2 =列1
column2 = column2 MATCH
栏3 =列1
栏3 = column2的
#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;
}
}
}
答案 1 :(得分:0)
问题在于标题行的输入。这包含一个末尾的换行符,它与数组中的项不匹配。删除换行符可以解决问题。
我正在使用Windows PC,然后将文件传输到Cent OS计算机以运行代码,两个平台之间的行结尾差异就是造成这个问题的原因。
将此作为调试语句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);
}