【问题标题】:C++: Read CSV-file separated by ; AND \n [duplicate]C++:读取由 ; 分隔的 CSV 文件和 \n [重复]
【发布时间】:2015-07-22 04:19:27
【问题描述】:

对不起,如果这只是纯粹的愚蠢,但我遇到了通过 C++ 读取文件的问题。 这是我要读取的 CSV 数据:

5;1;0;3;3;5;5;3;3;3;3;2;3;3;0
5;1;0;3;3;5;0;3;3;3;3;2;0;0;3
5;1;1;3;3;0;0;0;0;3;5;2;3;3;3
0;3;5;5;0;2;0;3;3;0;5;1;1;0;0
0;0;3;5;5;2;0;0;0;0;5;5;1;1;0
0;0;0;0;5;2;0;0;0;0;0;5;5;1;0
;;;;;;;;;;;;;;
Code;Bezeichnung;Kosten;;;;;;;;;;;;
0;Ebene;6;;;;;;;;;;;;
1;Fluss;10; (begrenzt nutzbar);;;;;;;;;;;
2;Weg;2;;;;;;;;;;;;
3;Wald;8;;;;;;;;;;;;
4;Brücke;5;;;;;;;;;;;;
5;Felswand;12;;;;;;;;;;;;

在这里,我想读取第一个值(由 ;;;; 分隔)并将其存储在二维数组中。如果它完全由';'分隔,那将不是问题。但是如果使用

while (getline(csvread, s, ';'))
{
[...]
}

我得到这样的信息:{5}{1}{0}{3}{3}{5}{5}{3}{3}{3}{3}{2}{3}{3}{0\n5}{1} 所以它基本上保存了换行符并且不认为它是分隔符。

那么即使您有两个分隔符,是否也可以选择使用 getline ?还是我完全关闭了? 我还考虑将它逐行读取到一个字符串中,添加一个 ;到字符串并将其重写到文件中,以便使用 ; 重用 getline。但这并不是最好的选择,对吧?

【问题讨论】:

  • 你能不能 sed 去掉其中一个分隔符,然后将结果通过管道传输到你的程序中?

标签: c++ csv getline


【解决方案1】:

您应该分别进行'\n'';' 拆分:

// here split into lines by '\n'
while (getline(csvread, line, '\n'))
{
    // in here, split line by ;
    std::vector<std::string> elems;
    boost::split(elems, line, boost::is_any_of(";"));

    // do something with elems
}

【讨论】:

    【解决方案2】:

    你可以使用这样的分割函数:

    std::vector<std::string> split(const std::string& source, const std::string& delimiter){
        std::vector<std::string> result;
    
        size_t last = 0;
        size_t next = 0;
    
        while ((next = source.find(delimiter, last)) != std::string::npos){ 
            result.push_back(source.substr(last, next - last));
            last = next + delimiter.length();
        } 
        result.push_back(source.substr(last));
        return result;
    }
    

    现在很简单:

    std::vector<std::vector<std::string>> parsedCSV;
    while (getline(csvread, s, '\n'))
    {
    parsedCSV.push_back(split(s,";"));
    }
    

    【讨论】:

      【解决方案3】:

      我最近也不得不阅读 csv-data 并偶然发现了相同的“问题”。这是我所做的:

      1. getline(csvread, s) 读入整行,这将读到第一个换行符。
      2. 在每次出现; 时拆分字符串,我使用this StackOverflow 答案作为拆分字符串的灵感,代码也在下面列出。

      我并不关心性能,因为我只需要运行这个程序一次,我不会评论这个解决方法的速度。

      祝你好运!

      编辑:显然 Boost 提供了拆分字符串的代码,这可能更简洁,如果您想避免 Boost,请考虑下面的代码。


      #include <string>
      #include <sstream>
      #include <vector>
      
      // source: https://stackoverflow.com/a/236803/4841248
      
      std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
          std::stringstream ss(s);
          std::string item;
          while (std::getline(ss, item, delim)) {
              elems.push_back(item);
          }
          return elems;
      }
      
      
      std::vector<std::string> split(const std::string &s, char delim) {
          std::vector<std::string> elems;
          split(s, delim, elems);
          return elems;
      }
      

      【讨论】:

        【解决方案4】:

        试试这样的:

        std::vector<std::string> cells;
        while (getline(csvread, s) ){
           boost::split(cells, s, boost::is_any_of(";"));
           ....
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-07
          • 2018-11-04
          • 2020-12-22
          • 1970-01-01
          • 2015-08-08
          • 2017-05-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多