DLV
DLV

Reputation: 200

Reading a text file (with integers) row by row and storing each row as a vector (C++)

I'm working on graph theory problems and using the adjacency list implementation. I have long text files which represent the adjacency list of graphs with N>100 vertices.

The text files are written in the following manner:

1 2 3

2 3 1

3 2

This will represent a graph of three vertices. The first number is the vertex, and the rest of the numbers in that row represent the adjacent vertices.

I have currently declared the adjacency list as

vector<vector<int> > adjList(N);

and my goal is to copy each row into each element of adjList.

I've read files using ifstream before, but these files were only to copy massive data sets into an array and I feel this problem is different.

How can I do this?

my current code looks like this:

ifstream inFile;
int N=200;
vector<vector<int> > adj(N);

inFile.open("/Users/davidvillarreal/Desktop/aaa.txt");
cout << "opened " << endl;
if (inFile.fail()) {
    cerr << "error encountered" << endl;
    exit(1);
}

Upvotes: 0

Views: 126

Answers (3)

PaulMcKenzie
PaulMcKenzie

Reputation: 35440

This small example, should show one way of doing this:

#include <vector>
#include <sstream>
#include <iostream>
#include <string>
#include <iterator>
//...
int main()
{
    // use a typedef to simplify things a bit 
    typedef std::vector<int> Int1D;
    typedef std::vector<Int1D> Int2D;

    // declare the adjacency list
    Int2D adjList;

    std::string line;
    std::ifstream infile;
    //...
    //..assume that infile has been opened successfully
    //...
    while (std::getline(infile, line))
    {
       // use a string stream to help parse the ints
       std::istringstream strm(line);
       int n;

       // add an empty row
       adjList.push_back(Int1D());

       // now fill in the last row we added by reading in the ints
       while (strm >> n)
          adjList.back().push_back(n);
    }

    // output results
    for (size_t i = 0; i < adjList.size(); ++i)
    {
       std::copy(adjList[i].begin(), adjList[i].end(), std::ostream_iterator<int>(std::cout, " "));
       std::cout << '\n';
    }
}

Live Example

Note that we have two loops -- the "read" loop, and the loop to add each int to the last added vector to the adjList. The usage of vector::back() gives us a reference to the last vector added to the list.

Upvotes: 1

DimChtz
DimChtz

Reputation: 4333

Yet another solution:

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

int main() {

   std::vector< std::vector<int> > data;
   std::ifstream file("data.txt");
   std::string line;

   if ( file ) {
       while(std::getline(file, line)) {
          std::stringstream sline(line);
          data.push_back(std::vector<int>( std::istream_iterator<int>( sline ), std::istream_iterator<int>() ));
      }
   }

   return 0;
}

Upvotes: 1

Zeta
Zeta

Reputation: 981

you can simply do like this.. if the file format is strictly one space and an integer .... and at the end new line..

vector<int> v;
vector<vector<int>> vv;
int i;
char c = ' ' ;
//repeat next until the eof
while(c != '\n') {
    f >> skipws >> i;
    v.push_back(i);
    f >> noskipws >> c;
}
vv.push_back(v);

Upvotes: 1

Related Questions