如何从文件中读取数字序列?

时间:2021-05-04 08:59:30

I've been trying to read sequences of numbers from a file to a 2D vector without significant success.

我一直试图从文件到2D矢量读取数字序列,但没有取得重大成功。

Data in sequences.txt

sequences.txt中的数据

1,2,3,4,5
6,3,1
7,4,10,4,1,9

I've encountered with few problems, reading sequences of numbers of an unknown length (format). For example if it was fixed a 3 number format, input would look like this:

我遇到了一些问题,读取未知长度(格式)的数字序列。例如,如果它被修复为3数字格式,输入将如下所示:

input_stream >> integer >> char >> integer >> char >> integer

But the number of numbers of each sequence is unknown...

但是每个序列的数量都是未知的......

Another problem is the ',' char, it isn't located at the end of each sequence, meaning that somehow I would have go through the line right to the very last number in a sequence, then pick it up after I finish going through the line, is that possible?

另一个问题是','char,它不是位于每个序列的末尾,这意味着我会以某种方式通过该行直接到序列中的最后一个数字,然后在我完成之后将其拾取这条线,可能吗?

My attempt of code:

我的代码尝试:

#include <fstream>
#include <iostream>
#include <vector>

void PrintMatrix(std::vector<std::vector<int>> matrix)
{
    for(auto v : matrix)
    {
        for(auto x : v)
        {
            std::cout << x << " ";
        }
        std::cout << std::endl;
    }
}

int main()
{
    std::fstream input_stream("sequences.txt", std::ios::in);
    if(!input_stream)
        std::cout << "Problem with opening a file";
    else
    {
        std::vector<std::vector<int>> matrix;
        while(input_stream.good())
        {
            std::vector<int> v;
            int number;
            char chr;
            while(input_stream >> number >> chr)
            {
                v.push_back(number);
            }
            matrix.push_back(v);
        }
        PrintMatrix(matrix);
    }
    return 0;
}

I started learning files very recently, I read most of the literature and now trying to practice, so any tips on how to solve this problem or any tips on working with files in general, I'd be very grateful :)

我最近开始学习文件,我阅读了大部分文献,现在正在尝试练习,所以关于如何解决这个问题的任何提示或者一般使用文件的任何提示,我都会非常感激:)

Thanks

P.S. Output that I get from this code (which is wrong): 1 2 3 4 5

附:我从这段代码得到的输出(这是错误的):1 2 3 4 5

Output I want to get:

我希望得到的输出:

1 2 3 4 5
6 3 1
7 4 10 4 1 9

2 个解决方案

#1


0  

Here is one possible solution, peek inside the loop where you read integers to determine whether you should move on to the next line

这是一个可能的解决方案,在循环内部查看整数,以确定是否应该继续下一行

#include <iostream>
#include <vector>
#include <cassert>

using std::cin;
using std::cout;
using std::endl;

int main() {
    auto data = std::vector<std::vector<int>>(1);
    auto integer = int{};
    auto current_line = 0;
    while (cin >> integer) {
        data[current_line].push_back(integer);

        // read the next character and if it is a newline add a new entry in
        // the data vector
        auto next_character = char{};
        if (cin.get(next_character)) {
            if (next_character == '\n') {
                data.emplace_back();
                ++current_line;
            }
        } else {
            break;
        }
    }

    for (const auto& vec : data) {
        for (auto integer : vec) {
            cout << integer << " ";
        }
        cout << endl;
    }

    return 0;
}

Also as noted in the comments, one thing to keep in mind is that you should be using the istream itself to check for eof and termination of a loop rather than calling .good() .eof() and the like.

同样如评论中所述,要记住的一件事是你应该使用istream本身来检查eof和循环的终止,而不是调用.good()。eof()等。

#2


0  

Here is another possible solution, using boost::split method for splitting the number in each of the lines.

这是另一种可能的解决方案,使用boost :: split方法分割每行中的数字。

#include <fstream>
#include <string>
#include <iostream>
#include <boost/algorithm/string.hpp>

void printMatrix(std::vector<std::vector<int> >& matrix)
{
    for(auto line : matrix)
    {
        for(auto num : line)
        {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    }
}

int main()
{
    std::ifstream in;
    std::string line;
    in.open("sequences.txt");
    std::vector<std::vector<int> > mat;

    while(std::getline(in, line))
    {
        std::vector<std::string> text;
        std::vector<int> nums;
        boost::split(text, line, boost::is_any_of(","));
        for(auto num : text)
            nums.push_back(std::stoi(num));

        mat.push_back(nums);
    }
    printMatrix(mat);
}

#1


0  

Here is one possible solution, peek inside the loop where you read integers to determine whether you should move on to the next line

这是一个可能的解决方案,在循环内部查看整数,以确定是否应该继续下一行

#include <iostream>
#include <vector>
#include <cassert>

using std::cin;
using std::cout;
using std::endl;

int main() {
    auto data = std::vector<std::vector<int>>(1);
    auto integer = int{};
    auto current_line = 0;
    while (cin >> integer) {
        data[current_line].push_back(integer);

        // read the next character and if it is a newline add a new entry in
        // the data vector
        auto next_character = char{};
        if (cin.get(next_character)) {
            if (next_character == '\n') {
                data.emplace_back();
                ++current_line;
            }
        } else {
            break;
        }
    }

    for (const auto& vec : data) {
        for (auto integer : vec) {
            cout << integer << " ";
        }
        cout << endl;
    }

    return 0;
}

Also as noted in the comments, one thing to keep in mind is that you should be using the istream itself to check for eof and termination of a loop rather than calling .good() .eof() and the like.

同样如评论中所述,要记住的一件事是你应该使用istream本身来检查eof和循环的终止,而不是调用.good()。eof()等。

#2


0  

Here is another possible solution, using boost::split method for splitting the number in each of the lines.

这是另一种可能的解决方案,使用boost :: split方法分割每行中的数字。

#include <fstream>
#include <string>
#include <iostream>
#include <boost/algorithm/string.hpp>

void printMatrix(std::vector<std::vector<int> >& matrix)
{
    for(auto line : matrix)
    {
        for(auto num : line)
        {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    }
}

int main()
{
    std::ifstream in;
    std::string line;
    in.open("sequences.txt");
    std::vector<std::vector<int> > mat;

    while(std::getline(in, line))
    {
        std::vector<std::string> text;
        std::vector<int> nums;
        boost::split(text, line, boost::is_any_of(","));
        for(auto num : text)
            nums.push_back(std::stoi(num));

        mat.push_back(nums);
    }
    printMatrix(mat);
}