Mosrour Tafadar
Mosrour Tafadar

Reputation: 9

How can I read as string and then make it int vector;

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!

Upvotes: 0

Views: 81

Answers (2)

WhozCraig
WhozCraig

Reputation: 66194

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?

Upvotes: 3

Patrick Xavier Silerio
Patrick Xavier Silerio

Reputation: 116

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.

Upvotes: 0

Related Questions