Hi guys, I need some help with file input output. I have a file that has a array size on the first line followed by a 2d array. The array size can change. I need to read this file, and place the array in a array variable. But im not quite sure how to handle this So far I am only able to pull the array size.

EX:
file.txt
4 4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

#include <iostream>
#include <fstream>
using namespace std;

int row;
int col;

void getSize(){
        ifstream infile ("maze1.txt", ios::in);
                if (infile.fail())
                {
                        ofstream outfile ("maze1.txt", ios::out);
                        if (outfile.fail())
                        {
                                cout << "Problems opening up maze1.txt" << endl;
                                exit (1);
                        }
                        outfile.close();
                }
        infile >> col >> row;
        infile.close();
}

main()
{
        getSize();
        cout << col << " " << row << endl;
}

Any help will be appreciated.

Recommended Answers

All 9 Replies

Use col and row to first of all allocate an array that matches the dimensions specified in the file, and secondly keep looping until you've filled up the array.

I recommend using getline() to grab entire lines, and then sending them into a stringstream to split up each individual number.

// hint: make this statement into a condition in a while loop
getline(infile, line);

// somewhere you need to keep an index of how many lines you've read.
// if this number is larger than 'rows', you need to exit, or you run
// the risk of overrunning the array boundaries.

// ...
istringstream iss(line);

// loop this for the amount in 'col'
iss >> someVariable;

Hope that sends you on the right track.

I had thought of using the getline function to get an entire row, but then how would I separate the string into individual array elements?

>how would I separate the string into individual array elements?
I just explained in my last post. Use stringstreams to separate the individual values, which you can then of course put into arrays using the index variables from your loops as array subscripts.

Oh sorry, Im unfamiliar with stringstreams. I will research them. Thank you for the help.

Ok, I've got it working... But I had to do something wierd and I don't quite understand why...

i have to index my array assignment by array[y][x-2] for it to assign the array correctly:

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

using namespace std;

int row;
int col;
char array[15][15];

void getMaze(){
    string line;
    int x = 0;
    int y = 0;
    istringstream instream;
    ifstream infile ("maze1.txt", ios::in);
        if (infile.fail())
        {
            ofstream outfile ("maze1.txt", ios::out);
            if (outfile.fail())
            {
                cout << "Problems opening up maze1.txt" << endl;
                exit (1);
            }
            outfile.close();
        }
    infile >> col >> row; 
    x=0;
    y=0;
    while(!infile.eof())
    {
        instream.clear();
        instream.str(line);
        getline(infile,line);
        while(y != row)
        {
            instream >> array[y][x-2];
            y++;
        }
        y = 0;
        x++;
    }
    infile.close();
}

main()
{
    getMaze();
    cout << col << " " << row << endl;

    for(int j = 0; j <= col; j++){
        for(int i=0; i <=row; i++){
            cout << array[i][j] << " ";
        }
        cout << endl;
    }
}

When you first grabbed the array dimensions from the file, you didn't use getline() . This leaves a newline character behind for getline() to grab, thus placing you -1 behind. I'm not sure about that other one, but something tells me there's another newline hidden that getline is grabbing.

[edit]

And see this about eof():
http://www.gidnetwork.com/b-58.html

Because you are trying to store integer values, instead of using a string value to store the line I'd use a char value, then use the atoi function to store the numbers...You could also use a typecast if you don't want to use char values...

unless the size is known at compile time, or there is an externally imposed constraint, it would be easier and less error prone to use a std::vector rather than a c-style array.

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <cassert>
#include <algorithm>
#include <iterator>
using namespace std ;

typedef vector< vector<int> > vec_2d ;

void read_it_in( const char* file_name, vec_2d& vec )
{
  ifstream file(file_name) ; assert(file) ;
  size_t row, col ; file >> row >> col ; 
  vec.clear() ; vec.resize(row) ;
  string line ; 
  getline( file, line ) ; // ignore rest of first line
  for( size_t i=0 ; i<row ; ++i )
  {
    assert( getline( file, line ) ) ;
    istringstream stm(line) ;
    istream_iterator<int> begin(stm), end ;
    copy( begin, end, back_inserter(vec[i]) ) ;
    assert( vec[i].size() == col ) ;
  }
}

int main()
{
  vec_2d vec ;
  read_it_in( "test.txt", vec ) ;
  for( size_t i=0 ; i<vec.size() ; ++i )
  {
    copy(  vec[i].begin(), vec[i].end(), ostream_iterator<int>(cout,"\t") ) ;
    cout << '\n' ;
  }
}
void read_it_in( const char* file_name, vec_2d& vec )
{
  ifstream file(file_name) ; assert(file) ;
  size_t row, col ; file >> row >> col ; 
  vec.clear() ; vec.resize(row) ;
  string line ; 
  getline( file, line ) ; // ignore rest of first line
  for( size_t i=0 ; i<row ; ++i )
  {
    assert( getline( file, line ) ) ;
    istringstream stm(line) ;
    istream_iterator<int> begin(stm), end ;
    copy( begin, end, back_inserter(vec[i]) ) ;
    assert( vec[i].size() == col ) ;
  }
}

there is a beginner's error in the code (line 10). it should have been

void read_it_in( const char* file_name, vec_2d& vec )
{
  ifstream file(file_name) ; assert(file) ;
  size_t row, col ; file >> row >> col ; 
  vec.clear() ; vec.resize(row) ;
  string line ; 
  getline( file, line ) ; // ignore rest of first line
  for( size_t i=0 ; i<row ; ++i )
  {
    getline( file, line ) ;
    assert( file ) ;
    istringstream stm(line) ;
    istream_iterator<int> begin(stm), end ;
    copy( begin, end, back_inserter(vec[i]) ) ;
    assert( vec[i].size() == col ) ;
  }
}

caused by my penchant, as already pointed out by Rashakil Fol, to do too much in one line of code. clearly not a good habit to have developed.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.