我正在读取CSV文件并将其存储在矢量向量字符串中。我想打印数据,为此,我使用两个for循环,一个在vector的向量上进行迭代,另一个在vector字符串的上进行迭代。
a1,b1,c1,d1
a1,b1,c4,d3
a1,b2,c2,d2
a2,b3,c3,d4
a2,b4,c3,d4
这是我正在读取的CSV数据。 我正在使用以下代码将其打印到屏幕上
void ReadCSV::printdata(vector<vector<string>> ipd){
for(auto it1 = ipd.begin();it1 != ipd.end();++it1){
vector<string> test = *it1;
for(auto it2 = test.begin();it2 != test.end();++it2){
string r = "";
r= *it2;
cout<<r<<" ";
}
cout<<endl;
}
}
但是我得到的输出似乎没有正确地迭代:
a1 b1 c1 d1
a1 b1 c1 d1 a1 b1 c4 d3
a1 b1 c1 d1 a1 b1 c4 d3 a1 b2 c2 d2
a1 b1 c1 d1 a1 b1 c4 d3 a1 b2 c2 d2 a2 b3 c3 d4
a1 b1 c1 d1 a1 b1 c4 d3 a1 b2 c2 d2 a2 b3 c3 d4 a2 b4 c3 d4
我使用下面的代码读取数据:
vector<vector<string>> ReadCSV:: ReadData(){
fstream fin(filename);
vector<string> temp;
string val1, val2, val3 ,val4;
if(!fin.is_open()){
cout<<"ERROR: file open";
}
cout<<"FIRST OUTPUT: "<<endl;
while(fin.good()){
getline(fin, val1,',');
//store
temp.push_back(val1);
cout<<val1<<" ";
getline(fin, val2,',');
temp.push_back(val2);
cout<<val2<<" ";
getline(fin, val3,',');
temp.push_back(val3);
cout<<val3<<" ";
getline(fin, val4,'\n');
temp.push_back(val4);
cout<<val4<<" ";
csvdata.push_back(temp);
}
cout<<endl;
return csvdata;
}
谁能告诉我我要去哪里错,我面临的另一个问题是当我运行调试器(ECLIPSE IDE)并将鼠标悬停在变量上时,它会打开一些弹出窗口,但不显示该变量的值,例如“ string” r”。 谢谢
答案 0 :(得分:0)
您的CSV阅读器除了有一些小问题外,还经过硬编码,可以精确读取4个逗号分隔的值。这是更通用的代码,可以读取多行,并且每行具有可变数量的逗号分隔值。
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
template<typename In, typename Out>
void csv2vec(In first, In last, Out& result) {
std::string temp;
unsigned i{0};
while(1) {
do{
if(*first == '\n') break;
temp.push_back(*first);
++first;
}while(*first != ',' && first != last);
result[i].push_back(temp);
if(*first == '\n') {
++i;
result.resize(i+1);
}
temp.clear();
if(first == last) break;
++first;
}
}
int main(void) {
std::vector<std::vector<std::string>> vec(1);
std::ifstream in("data.txt");
std::istreambuf_iterator<char> begin(in);
std::istreambuf_iterator<char> end;
csv2vec(begin,end,vec);
for(const auto& vecouter : vec) {
for(const auto& elem : vecouter){
std::cout<<elem<<" ";
}
std::cout<<"\n";
}
return 0;
}
注意::我使用过istreambuf_iterator,它从不跳过任何字符(包括空格,例如'\ n')。它与流跳过缓冲区的istream_iterator不同,它捕获流缓冲区中的下一个内容。同样,istream_iterator在执行格式化输入时很有用,并且比istreambuf_iterator慢。 参考:第29项,有效STL,斯科特·迈耶斯。