C++ 将 CSV 文件解析为向量向量:丢失字符串第一个字符

Yak*_*sha 1 c++ csv string file vector

我正在将 CSV 文件读入字符串向量向量中。我在下面写了代码。

#include<iostream>
#include<fstream>
#include<string>
#include <vector>
#include <fstream>
#include <cmath>
#include <sstream>

using namespace std;

int main()
{
    ifstream mesh;
    mesh.open("mesh_reference.csv");

    vector<vector<string> > point_coordinates;
    string line, word;

    while (getline(mesh,line))
    {
        stringstream ss(line);
        vector<string> row;
        while (getline(ss, word, ','))
        {
            row.push_back(word);
        }
        point_coordinates.push_back(row);
    }

    for(int i=0; i<point_coordinates.size(); i++) 
    {
        for(int j=0; j<3; j++)
            cout<<point_coordinates[i][j]<<" ";
        cout<<endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我打印出向量的向量时,我发现我在向量行的 0 位置丢失了 Element 的第一个字符。基本上,point_coordinates[0][0]显示的是 0.0001,而字符串应该是 -0.0001。我无法理解其原因。请帮忙。

典型的输出线是

 .0131 -0.019430324 0.051801
Run Code Online (Sandbox Code Playgroud)

而 CSV 数据是

0.0131,-0.019430324,0.051801
Run Code Online (Sandbox Code Playgroud)

文件中的 CSV 数据示例

    NODES__X,NODES__Y,NODES__Z
    0.0131,-0.019430324,0.051801
    0.0131,-0.019430324,0.06699588
    0.0131,-0.018630324,0.06699588
    0.0131,-0.018630324,0.051801
    0.0131,-0.017630324,0.050801
    0.0131,-0.017630324,0.050001
    0.0149,-0.017630324,0.050001
    0.0149,-0.019430324,0.051801
Run Code Online (Sandbox Code Playgroud)

Arm*_*gny 5

虽然问题已经解决,但我想向您展示一个使用一些现代 C++ 算法并消除小问题的解决方案。

  • 不使用using namespace std;。你不应该这样做
  • 不需要单独的 file.open。构造函数std::ifstream将为您打开该文件。析构函数将关闭它
  • 检查文件是否可以打开。操作员ifstreams !超载。所以你可以做一个布尔检查
  • 不要int在与 进行比较的 for 循环中使用.size()。使用 ````size_t 代替
  • 始终初始化所有变量,即使下一行中有赋值
  • 对于标记化,您应该使用std::sregex_token_iterator. 它正是为此目的而设计的
  • 在现代 C++ 中,鼓励您使用算法

请参阅下面的代码的改进版本:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <regex>

const std::regex comma(",");

int main()
{
    // Open source file.
    std::ifstream mesh("r:\\mesh_reference.csv");

    // Here we will store the result
    std::vector<std::vector<std::string>> point_coordinates;

    // We want to read all lines of the file
    std::string line{};
    while (mesh && getline(mesh, line)) {
        // Tokenize the line and store result in vector. Use range constructor of std::vector
        std::vector<std::string> row{ std::sregex_token_iterator(line.begin(),line.end(),comma,-1), std::sregex_token_iterator() };
        point_coordinates.push_back(row);
    }
    // Print result. Go through all lines and then copy line elements to std::cout
    std::for_each(point_coordinates.begin(), point_coordinates.end(), [](std::vector<std::string> & vs) {
        std::copy(vs.begin(), vs.end(), std::ostream_iterator<std::string>(std::cout, " ")); std::cout << "\n"; });

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果您将来可能想使用这种方法,请考虑