在C ++中将文件读入三个不同的向量

时间:2018-03-25 22:55:14

标签: c++

我有一个空格分隔的文件,看起来很像:

4 55 -1.8
4 61 -1.8
2 37 -1.56739
9 1 -1.23
29 8 -1.918
4 57 -1.2
54 63 -1.118012

我写了下面的代码,一行一行地读到了vetors:

#include <iostream>
#include <vector>
#include <string>

int main() {

    std::vector<int> row1 = {};
    std::vector<int> row2 = {};
    std::vector<double> row3 = {};

    int row1val, row2val;
    double row3val;

    std::string line;
    // read input a line at a time until end-of-file
    while (std::getline(std::cin, line))
    {
        std::cin >> row1val >> row2val >> row3val;
        row1.push_back(row1val);
        row2.push_back(row2val);
        row3.push_back(row3val);
    }

    std::cout << row1[0] << " " << row2[0] << " " << row3[0] << std::endl;
    return 0;
}

我认为有很多问题:

1)第一行数据不存储在向量中。

2)代码看起来非常不优雅,比如使用line和变量s row1val等。有没有办法简化它?

1 个答案:

答案 0 :(得分:1)

您正在通过调用std::cin并使用格式化输入来阅读getline()。你可能想要坚持一个或另一个。

while (std::cin >> row1val >> row2val >> row3val)
{
    row1.push_back(row1val);
    row2.push_back(row2val);
    row3.push_back(row3val);
}

这个风险是它会接受比三个元素更短或更长的行,&#34;窃取&#34;来自下一行的元素。

为了避免这种风险,您只需使用getline()cin读取,然后解析生成的缓冲区:

while (std::getline(std::cin, line))
{
    std::istringstream linebuf(line);
    if( linebuf >> row1val >> row2val >> row3val) {
        row1.push_back(row1val);
        row2.push_back(row2val);
        row3.push_back(row3val);
    }
}

修改

为了避免临时变量和row1val等的重复,您可以创建一个类,并将数据存储在该类的单个向量中,而不是三个向量。这是一个完整的示例程序。请注意,它包括基于getline()和格式化输入的解决方案供您选择。

无论您选择哪个operator>>,请注意main()函数变得多么简单。

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

struct row_t {
    int row1val, row2val;
    double row3val;
    friend std::istream& operator>>(std::istream&is, row_t& r) {
#ifdef USE_GETLINE
        std::string line;
        if(std::getline(is, line) &&
           std::istringstream(line) >> r.row1val >> r.row2val >> r.row3val) {
            return is;
        }
        is.setstate(std::ios::failbit);
        return is;
#else
        return is >> r.row1val >> r.row2val >> r.row3val;
#endif
    };
};

int main() {
    std::vector<row_t> rows((std::istream_iterator<row_t>(std::cin)),
                             std::istream_iterator<row_t>());


    std::cout << rows[0].row1val << " " << rows[0].row2val << " " << rows[0].row3val << std::endl;
    std::cout << rows.size() << "\n";
    return 0;
}