【问题标题】:read csv string into vector C++将csv字符串读入向量C++
【发布时间】:2021-09-18 23:36:38
【问题描述】:

csv 到矢量有很多选项,包括read a csv file and and add its all data into vector in c++,但是我想要一些高于或低于csv -> vector 的东西。相反,我有一个 CURL 函数,可以将 csv 数据加载到 std::string 中,格式为

col1,col2,col3
abc,2,ghi
jkl,2,pqr

其中,每一行由\n 分隔。如何将此给定结构中的数据解析为std::vector<data>

数据看起来像这样的地方

struct data
{
  std::string col1, col3;
  int col2;
};

【问题讨论】:

  • std::stringstream而不是fstream读取。
  • @MikeCAT 我该怎么做?格式是整个std::string 用逗号和\n 分隔,我想成为std::vector 中的一个新条目
  • std::istringstream stream(myString); 那么代码与从 fstream 的一行进行处理的代码相同。
  • @drescherjm 但是我必须把它分开\n
  • @MikeCAT 另外,假设它是一个巨大的std::string,那么仅仅构造一个全新的stringstream 并以某种方式将数据加载到最初的stringstream 中不是效率低下吗? ?

标签: c++ string csv parsing vector


【解决方案1】:

如果您只需要在应用程序中创建解析器,您可以像这样构建一些简单的流式递归解析器:

#include <cctype>
#include <cstring>
#include <vector>
#include <string>
#include <iostream>

struct data
{
  std::string col1;
  int col2;
  std::string col3;
};

std::ostream& operator<<(std::ostream& to,const data& d)
{
    to << d.col1 << ',';
    to << d.col2 << ',';
    to << d.col3;
}

static char* skip_spaces(const char* csv)
{
  constexpr const char* WHITESPACE = "\t\n\v\f\r ";
  return const_cast<char*>( csv + std::strspn(csv,WHITESPACE) );
}


static const char* parse_csv_line(const char* csv, data& to)
{
  char* b = skip_spaces(csv);
  char* e = std::strchr(b,',');
  to.col1 = std::string(b,e);
  b = skip_spaces(e+1);
  e = std::strchr(b,',');
  to.col2 = std::strtol(b,&e,10);
  b = skip_spaces(e+1);
  e = std::strchr(b,'\n');
  if(nullptr == e) {
    e = b + std::strlen(b);
  }
  to.col3 = std::string(b,e);
  return ('\0' == *e) ? nullptr : e + 1;
}

std::vector<data> parse_csv(const char* csv)
{
  std::vector<data> ret;
  // skip header
  csv = std::strchr(csv,'\n');
  while(nullptr !=  csv) {
    data next;
    csv = parse_csv_line(csv, next);
    ret.push_back( next );
  }
  return ret;
}


int main(int argc, const char** argv)
{
  const char* CSV = "col1,col2,col3,\r\nabc,2,ghi\r\njkl,2,pqr";
  std::vector<data> parsed = parse_csv(CSV);
  for(auto d: parsed) {
    std::cout << d << std::endl;
  }
  return 0;
}

如果您需要更复杂的东西,例如处理错误等,请使用 CSV parsing library

【讨论】:

  • 嗨,很抱歉,我没有正确澄清我的问题,请查看我的编辑。
  • @asjhdbashjdbasjhdbhjb 完全没问题,看我的更新
  • 有什么我需要free(),因为它返回char*'s?
  • 效果很好,将369 KB csv文件加载到向量中大约需要8毫秒!
  • 他们正在操纵原始指针,即内存地址——就像汇编一样。它可以是堆栈或堆 - 没关系。您可以确定内存不会发生变化,因为 C 标准库没有错误。
猜你喜欢
  • 2019-07-05
  • 2022-01-17
  • 2019-12-10
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 2014-02-12
  • 2019-11-21
  • 2020-02-27
相关资源
最近更新 更多