C ++读取CSV文件直到行结束,而不是查找最后一个单元格

时间:2018-04-18 15:48:25

标签: c++ csv parsing getline

我正在读取一个CSV文件,该文件包含不同长度的列,如下所示:

1,2,3,4\n
5,,7,\n
9,,11,\n

我的问题是我希望它将以下内容读入矢量:

1 2 3 4
5 nan 7 nan
9 nan 11 nan

所以我使用以下内容:

int i = 0;
while(getline(data,line))               // Read each line
{
std::stringstream lineStream(line);     
while(getline(lineStream,cell,','))     // Read each cell in the line
{
    if(cell.empty())                    // If ,, use NaN
    {
        strains.push_back(std::numeric_limits<double>::quiet_NaN());
    }
    else
    {
        strains.push_back(std::stod(cell));
    }
}
}

问题在于它正在跳过结束这些行的空单元格,所以它正在输出:

1 2 3 4
5 nan 7 9
nan 11

你们都知道我怎么能计算最后一栏,即使它是空的吗?我正在考虑有一个“if row length&lt; 4,添加空单元格”的东西。谢谢

编辑我用最后一件事修好了,我把一个计数器计算了多少个单元格,然后在内部循环的末尾我添加了:

if(j<cols) // If counted less than 12 columns,
{
    strains.push_back(std::numeric_limits<double>::quiet_NaN());
}

如果您对此有任何建议或更正,谢谢。

1 个答案:

答案 0 :(得分:0)

这是解析字符串流输入的另一种方法。我制作了一个示例程序,说明了使用getline的另一种方法。我会做一个完整的功能,但你原来的问题没有,所以我添加了很多评论。

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <array>
#include <algorithm>
#include <functional>

int main()
{
  // Test cases.
  std::istringstream lineStream("1,2,3,4\n");
  //std::istringstream lineStream("5,,7,\n");
  //std::istringstream lineStream("9,,11,\n");

  // Vector of 10-char arrays
  std::vector<std::array<char, 10>> output;
  // "NaN" array, instead of recreating it each iteration.
  std::array<char, 10> NaN = { 'N', 'a', 'N'};

  // Split lineStream on 10 characters, or comma, in cell variable.
  // NOTE : Here, I assume you have maximum 10 characters field, but adjust
  // this based on your specific case. Also, this will capture the "\n", so
  // we'll need to handle that.
  for (std::array<char, 10> cell; lineStream.getline(&cell[0], 10, ','); )
  {
      // Replace the \n character with an end of string.
      // NOTE : this is basic character filtering, and doesn't handle
      // tabulations, or windows-style endline, so it should probably be
      // more robust.
      std::replace(cell.begin(), cell.end(), '\n', '\0');

      // Check if cell is empty, and assign it "NaN"      
      if((cell[0] == '\0') || (cell.empty()))
        cell = NaN;
      // Push the cell back to the output vector.
      output.push_back(cell);
  }

  // Display the output vector
  for (auto& a : output)
  {
    std::cout << &a[0] << " ";
  }