用C++实现快速,简单的CSV解析

Kyl*_*nch 9 c++ csv standard-library

我试图解析一个简单的CSV文件,其格式如下:

20.5,20.5,20.5,0.794145,4.05286,0.792519,1
20.5,30.5,20.5,0.753669,3.91888,0.749897,1
20.5,40.5,20.5,0.701055,3.80348,0.695326,1
Run Code Online (Sandbox Code Playgroud)

所以,一个非常简单和固定的格式文件.我将这些数据的每一列存储到STL向量中.因此我尝试使用标准库保持C++方式,并且我在循环中的实现看起来像:

string field;
getline(file,line);
stringstream ssline(line);

getline( ssline, field, ',' );
stringstream fs1(field);
fs1 >> cent_x.at(n);

getline( ssline, field, ',' );
stringstream fs2(field);
fs2 >> cent_y.at(n);

getline( ssline, field, ',' );
stringstream fs3(field);
fs3 >> cent_z.at(n);

getline( ssline, field, ',' );
stringstream fs4(field);
fs4 >> u.at(n);

getline( ssline, field, ',' );
stringstream fs5(field);
fs5 >> v.at(n);

getline( ssline, field, ',' );
stringstream fs6(field);
fs6 >> w.at(n);
Run Code Online (Sandbox Code Playgroud)

问题是,这非常慢(每个数据文件有超过100万行),在我看来有点不优雅.有没有更快的方法使用标准库,或者我应该只使用stdio函数?在我看来,整个代码块将减少为单个fscanf调用.

提前致谢!

jro*_*rok 9

使用7个字符串流时只需一个肯定无法帮助wrt.性能.试试这个:

string line;
getline(file, line);

istringstream ss(line);  // note we use istringstream, we don't need the o part of stringstream

char c1, c2, c3, c4, c5;  // to eat the commas

ss >> cent_x.at(n) >> c1 >>
      cent_y.at(n) >> c2 >>
      cent_z.at(n) >> c3 >>
      u.at(n) >> c4 >>
      v.at(n) >> c5 >>
      w.at(n);
Run Code Online (Sandbox Code Playgroud)

如果您知道文件中的行数,则可以在读取之前调整向量的大小,然后使用operator[]而不是at().这样就可以避免边界检查,从而获得一点性能.

  • 小事:一个字符吃掉逗号就足够了 (2认同)