0

Lets say I have txt.file as

7 8 9
10 11 1
14 15 1

I want to keep the line and then put them in a nested vector. I have done this:

#include <sstream>
#include <fstream>

using namespace std;

int main()
{

    vector<vector<int> > data;
    vector<int> temp;

    string file;

    cout << "Enter a file: ";
    cin >> file;

    ifstream infile(file);

    if (!infile.good()) {

        cout << "Enter a  valid file: " << endl;
        return 1;
    }

    string read;
    while (!infile.eof()) {

        getline(infile, read);
        istringstream iss(read);

        copy(istream_iterator<int>(iss), istream_iterator<int>(), back_inserter(temp));

        data.push_back(temp);
    }

    for (int i = 0; i < data.size(); i++) {
        for (int j = 0; j < data[i].size(); j++) {
            cout << data[i][j] << " ";
        }
        cout << endl;
    }
}

Now the output I get is like this:

7 8 9 
7 8 9 10 11 1 
7 8 9 10 11 1 14 15 1 

I am not sure why previous content is repeating. Any help would be appreciated. Thank you!

a.Li
  • 1,228
  • 3
  • 8
  • 18
  • You should declare temp inside the while-loop body. With C++11 or later you can simply do: `data.emplace_back(istream_iterator{iss}, istream_iterator{});` – van con Nguyen Jan 14 '21 at 04:47
  • Compile with a *recent* [GCC](http://gcc.gnu.org/) invoked as `g++ -Wall -Wextra -g` then use [GDB](https://www.gnu.org/software/gdb/) – Basile Starynkevitch Jan 14 '21 at 09:59

2 Answers2

3

Among the multitude of things wrong.

  1. You use std::cin and std::cout, but never #include <iostream>
  2. You use std::vector, but never #include <vector>
  3. You use std::string, but never #include <string>
  4. You append your populated line vector, but never reset the vector.

Note that you don't have to do (4) if you simply ensure the vector being appended from is, in fact, in local scope and as such expires before the next line. Better still, just use a temporary (which I'll demonstrate next).

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

int main()
{
    std::vector<std::vector<int>> data;

    std::cout << "Enter a file: ";
    std::cout.flush();

    std::string filename;
    if (std::cin >> filename)
    {
        std::ifstream file(filename);
        if (file.is_open())
        {
            std::string line;
            while (std::getline(file, line))
            {
                std::istringstream iss(line);
                data.emplace_back(
                    std::istream_iterator<int>{iss},
                    std::istream_iterator<int>{});
            }
        }
    }

    for (auto const &v : data)
    {
        for (auto x : v)
            std::cout << x << ' ';
        std::cout.put('\n');
    }
}

A notable problem fixed here is the avoidance of using std::istream::eof in a loop conditional. It is rarely correct, and in your case, it was wrong. See this question and answers for why: Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())) considered wrong?

WhozCraig
  • 59,130
  • 9
  • 69
  • 128
0

back_inserter(temp) is adding your next lines to temp but you don't reset the variable so every line is appended to the end.

  • Thank you so much for answering. Would you mind to share how can I reset variable so that line is not appended to the end. Thank you so much again. – Mosrour Tafadar Jan 14 '21 at 04:49