【问题标题】:C++ File Reading Line by Line [duplicate]C ++文件逐行读取[重复]
【发布时间】:2020-02-21 03:54:45
【问题描述】:

我正在尝试逐行读取文件。我的文件有点像这样:

4 558 5

123 145 782

x 47 45 789

如果第一个字符是 a,我想将它前面的三个值存储在一个数组中。我正在尝试这个,但它似乎不起作用:

 while (std::getline(newfile, line))
    {
        if (line[0] == 'a')
        {
            vertex[0] = line[1];
            vertex[1] = line[2];
            vertex[2] = line[3];
            //vertices.push_back(vertex);
        }

【问题讨论】:

  • 请提供minimal reproducible exampleline[1] 是该行 ' ' 中的第二个字符。这不是第一个数字。
  • if (line.empty()) continue; 作为循环体的第一行可能更安全一些。

标签: c++ file getline


【解决方案1】:

我正在尝试,但它似乎不起作用:

当你使用

vertex[0] = line[1];

line 的第 1 个字符分配给 vertex[0]。这不是你的本意。您想将该行中a 之后的第一个数字分配给vertex[0]

您可以使用std::istringstream 提取数字。

if (line[0] == 'a')
{
   // Make sure to ignore the the first character of the line when
   // constructing the istringstream object.

   std::istringstream str(&line[1]);
   str >> vertex[0] >> vertex[1] >> vertex[2];
}

【讨论】:

  • @sweenish,C++ 标准库工具箱中的工具数量相当多。我仍在标准库中发现有用的东西。
【解决方案2】:

这段代码包含了关于这一点的建议和答案。

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

int main()
{
    std::ifstream newfile("vals");
    if (!newfile)
        std::cout << "Exiting...\n";
    std::string line;
    int vertex[3][3];

    int i = 0;
    while(std::getline(newfile, line)) {
        if (line.empty()) continue;
        if (line[0] == 'a') {
            // Make sure to ignore the the first character of the line when
            // constructing the istringstream object.
            std::istringstream str(&line[1]);
            str >> vertex[i][0] >> vertex[i][1] >> vertex[i][2];
        }
        ++i;
    }
    newfile.close();

    for (int j = 0; j < 3; ++j) {
        for (int k = 0; k < 3; ++k) {
            std::cout << vertex[j][k] << ' ';
        }
        std::cout << '\n';
    }
}

问题是变量linestd::string,在字符串上使用[n] 会得到字符和索引n,而你正试图得到第n 个单词。

另一种解决方法(为了学习,上面的代码使用首选方法)是自己手动提取数字。

#include <fstream>
#include <string>
#include <iostream>

int main()
{
    std::ifstream newfile("vals");
    if (!newfile)
        std::cout << "Exiting...\n";
    std::string line;
    int vertex[3][3];

    int i = 0;
    while(std::getline(newfile, line)) {
        if (line.empty()) continue;
        if (line[0] == 'a') {
            line = line.substr(2);
            int j = 0;
            std::string::size_type loc;
            do {
                loc = line.find_first_of(" ");
                std::string tmp = line.substr(0, loc);
                vertex[i][j] = std::stoi(tmp);
                line = line.substr(loc + 1);
                ++j;
            } while(loc != std::string::npos);
        }
        ++i;
    }
    newfile.close();

    for (int j = 0; j < 3; ++j) {
        for (int k = 0; k < 3; ++k) {
            std::cout << vertex[j][k] << ' ';
        }
        std::cout << '\n';
    }
}

应该很清楚为什么首选 stringstream 方法。此方法手动切分行并将提取的数字(仍存储为字符串)手动转换为int 以存储在数组中。同时,上述方法对你隐藏了很多肮脏的工作,而且工作效率也很高。虽然我可能不必在第二个示例中继续修剪变量line(但我需要另一个变量),但我的反驳是我根本不会首先选择这条路线。

【讨论】:

    猜你喜欢
    • 2015-05-19
    • 2023-03-27
    • 2017-08-29
    • 2014-06-21
    • 2012-06-13
    • 1970-01-01
    • 2018-07-10
    • 2012-09-05
    • 1970-01-01
    相关资源
    最近更新 更多