【问题标题】:Understadint using getilne in specific example了解在具体示例中使用 getilne
【发布时间】:2021-02-21 21:08:03
【问题描述】:

我知道我要问的问题可能重复,但鉴于类似问题的答案,我无法解决问题。我刚开始使用C++,对它不是很熟悉。

我在读取 4 列和近 28000 行的 CSV 文件时遇到以下问题。问题在于我无法理解 std::getline() 函数,在打印结果之前我以为我知道它的行为。

变量的名称确实与项目有关,所以如果代码可读性不强,我很抱歉,我决定将s_index称为“开始索引”,将e_index称为“结束索引” ",同样v_boolean 是一个布尔向量,我的结构的通用节点NodeGraph 是一个Node,它表示一个面向Graph 的公共交通的节点(整数),用vector 初始化。

代码如下:

// Reading network_walk.csv
cout << "Reading network_walk.csv" << endl;

ifstream thirdfile;
string thirdfile_line;

thirdfile.open("network_walk.csv");
getline(thirdfile,thirdfile_line); // Skip the first row

while(!thirdfile.eof()) {

    getline(thirdfile, thirdfile_line, ';');

    int s_index = atoi(thirdfile_line.c_str());

    getline(thirdfile, thirdfile_line, ';');
    int e_index = atoi(thirdfile_line.c_str());

    cout << s_index << " " << e_index << "" <<endl;

    if (v_boolean[s_index]*v_boolean[e_index] == true ) {

        NodeGraph Node;

        Node.to_stop_I = e_index;

        getline(thirdfile, thirdfile_line, ';');
        Node.arr_time = (atoi(thirdfile_line.c_str()))*36.0 /50.0;

        getline(thirdfile, thirdfile_line, ';'); //Ignore the third data.

        Node.route_type = -1;

        Graph[s_index].push_back(Node);

    }

    getline(thirdfile, thirdfile_line);
}

thirdfile.close();

我应该得到的和我实际得到的如下所示:

【问题讨论】:

  • 目前还不清楚实际问题是什么。请说清楚。此外,CSV 文件的实际外观是什么样的,您希望从中得到什么样的输出?
  • 我想打印 csv 文件中完全相同的行,但它似乎跳过了一些行
  • 再次,实际的 CSV 文件是什么样的?它到底有多少列?实际上跳过了什么?请提供一个更简单的例子。此外,请考虑先将文件中的每一行读入std::string,然后根据需要使用单独的std::istringstream 从该std::string 中解析出值。
  • 我认为问题很明显,例如,第一行(例如,to_stop_id = 6657)被跳过,您可以在输出中看到应该代表前 $$n$$ 行
  • "我认为问题很明确" - 你当然会,因为你是提出问题的人。但是对于想要帮助您的其他人,需要更多详细信息。当您没有提供minimal reproducible example 来演示实际问题时,您如何期望任何人帮助您。再说一遍,CSV 文件实际上是什么样子的?请提供前几行,以便我们实际了解您正在处理的内容以及缺少的内容。

标签: c++ csv vector struct getline


【解决方案1】:

您尚未显示原始 CSV 文件数据,但您的代码取决于在 EOL 之前由 ; 终止的第 4 列。您的屏幕截图并未显示实际情况是否如此,但如果第 4 列未由 ; 终止,则当您的 v_boolean[] 元素评估为 true 时 I can reproduce the issue。读取第 4 列值将通过 EOL 读取到下一行的第 1 列,然后最终的 getline() 将跳过下一行的其余部分,因此您跳过读取该行的第 2-4 列。另一方面,当 v_boolean 元素的计算结果为 false 时,您会跳过第 3 列和第 4 列的读取,并且最终的 getline() 会按照预期读取直到当前行的 EOL。

当您指定终止符时,'\n'std::getline() 不会像预期的那样在 EOL 上停止读取。

解决方案是使用std::getline() 一次读取整行,然后根据需要使用std::istringstream 解析每行的值。那么第 4 列是否以; 结尾都没有关系。

试试这个:

// Reading network_walk.csv
cout << "Reading network_walk.csv" << endl;

ifstream thirdfile;
string thirdfile_line;

thirdfile.open("network_walk.csv");
getline(thirdfile, thirdfile_line); // Skip the first row

while (getline(thirdfile, thirdfile_line)) {

    istringstream iss(thirdfile_line);
    string thirdfile_value;

    getline(iss, thirdfile_value, ';');
    int s_index = atoi(thirdfile_value.c_str());

    getline(iss, thirdfile_value, ';');
    int e_index = atoi(thirdfile_value.c_str());

    cout << s_index << " " << e_index << "" <<endl;

    if (v_boolean[s_index]*v_boolean[e_index]) {

        NodeGraph Node;

        Node.to_stop_I = e_index;

        getline(iss, thirdfile_value, ';');
        Node.arr_time = (atoi(thirdfile_value.c_str()))*36.0 /50.0;

        Node.route_type = -1;

        Graph[s_index].push_back(Node);
    }
}

thirdfile.close();

或者,考虑使用operator&gt;&gt; 而不是getline() 来读取单个整数,例如:

// Reading network_walk.csv
cout << "Reading network_walk.csv" << endl;

ifstream thirdfile;
string thirdfile_line;

thirdfile.open("network_walk.csv");
getline(thirdfile, thirdfile_line); // Skip the first row

while (getline(thirdfile, thirdfile_line)) {

    istringstream iss(thirdfile_line);
    int s_index, e_index;

    iss >> s_index;
    iss.ignore(numeric_limits<streamsize>::max(), ';');

    iss >> e_index;
    iss.ignore(numeric_limits<streamsize>::max(), ';');

    cout << s_index << " " << e_index << "" <<endl;

    if (v_boolean[s_index]*v_boolean[e_index]) {

        NodeGraph Node;

        Node.to_stop_I = e_index;

        int temp;
        iss >> temp;
        Node.arr_time = temp * 36.0 / 50.0;

        Node.route_type = -1;

        Graph[s_index].push_back(Node);
    }
}

thirdfile.close();

【讨论】:

    猜你喜欢
    • 2022-08-17
    • 2017-01-29
    • 2012-10-14
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多