CHID
CHID

Reputation: 1643

How do I read input from files?

I am trying to read input from file into an array. I seem to have done the needful, yet the code is not working as it should. Please tell me where am i going wrong. This s my code:

int pb[10][10];
int i,j,n;
string ip_filename = string("pro.txt");

    ifstream fil1;

    fil1.open(ip_filename.c_str());

// to store the probabilities of the nodes
for(i=0;i<num_rows;i++)
    for(j=0;j<num_cols;j++)
    fil1 >> pb[i][j];

fil1.close();

for(i=0;i<num_rows;i++)
{
for(j=0;j<num_cols;j++)
    cout<<pb[i][j]<<" ";
cout<<endl;
}

The text file is in the same directory as the cpp file is. While printing the output, it just prints 0 irrespective of the value in the file.

The values in the file is store as follows

0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

num_rows and num_cols are defined previously in the code, both have the value 4.

Upvotes: 0

Views: 1528

Answers (5)

James Kanze
James Kanze

Reputation: 154037

What is the status of the stream after each operation? You shouldn't be reading without verifying. And you shouldn't be reading without having verified that the open worked:

ifstream fill( ip_filename.c_str() );
if ( !fill ) {
    //  error handling, open failed...
}

After that, I would agree with the suggestion of reading line by line:

int row = 0;
string line;
while ( getline( fill, line ) && row < size( pb ) ) {
    istringstream sLine( line );
    int col = 0;
    int tmp ;
    while ( sLine >> tmp && col < size( pb[ row ] )) {
        pb[row][col] = tmp;
        ++ col;
    }
    if ( col != size( pb[ row ] ) ) {
        //  Input error, too few entries
    } else if ( sLine >> ws && sLine.get() != EOF ) {
        //  Input error, garbage at end of line <row>
    }
    ++ row;
}
if ( row != size( pb ) ) {
    //  Input error, garbage at end of file
}

Alternatively, you could decide on the dimensions dynamically, according to the input:

std::vector<std::vector<int> > pb;
ifstream fill( ip_filename.c_str() );
if ( !fill ) {
    //  error handling, open failed...
}
string line;
while ( getline( fill, line ) ) {
    std::vector<int> tmp1;
    istringstream sLine( line );
    int tmp2;
    while ( sLine >> tmp2 ) {
        tmp1.back().push_back( tmp2 );
    }
    if ( sLine >> ws && ! sLine.eof() ) {
        //  input error: non-numeric data in line
    } else if ( ! pb.empty() && tmp1.size() != pb.back().size() ) {
        //  input error : inconsistent number of columns.
    }
}
//  Check here if square matrix required.

Upvotes: 0

Dave Rager
Dave Rager

Reputation: 8160

This code works perfectly fine for me with pro.txt formatted like you show:

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

using namespace std;

int main()
{
    int num_rows = 4;
    int num_cols = 4;
    int pb[10][10];
    int i,j,n;
    string ip_filename = string("pro.txt");

    ifstream fil1;

    fil1.open(ip_filename.c_str());

    // to store the probabilities of the nodes
    for(i=0;i<num_rows;i++)
        for(j=0;j<num_cols;j++)
            fil1 >> pb[i][j];

    fil1.close();

    for(i=0;i<num_rows;i++)
    {
        for(j=0;j<num_cols;j++)
            cout<<pb[i][j]<<" ";
        cout<<endl;
    }

}

My suggestion would be to ensure that pro.txt is in the same directory as you .exe file. If you are using an IDE to build this code it is likely a different directory from your .cpp files.

Upvotes: 1

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76876

Usually the simplest way to do these kinds of things is to store the data in a flat array (or even better a std::vector), and the use simple arithmetics to access the elements by rows and columns. This makes things much simpler.

A wrapper for this could look like this:

template<int ColumnCount>
class MyMatrix {
public:
    template<class T>
    MyMatrix(T & begin, T & end) : data(begin, end) {}

    int getItem(int i, int j) const {
        return data[i*ColumnCount+j];
    }
private:
    std::vector<int> data;
};

Then you can read the data like this:

std::ifstream file1("pro.txt");
std::istream_iterator<int> begin(file1);
std::istream_iterator<int> end;

MyMatrix<4> m(begin, end);

Upvotes: 0

Andrei Bularca
Andrei Bularca

Reputation: 1024

As i see you want to load a matrix from a file. In file your values are stored as string separated by space. So you should load your file, read the file line by line, separate your string into a string array and the convert your values from string to int and store them into your matrix.

Upvotes: 0

stefaanv
stefaanv

Reputation: 14392

When using fstream, for robust coding, it is best to check error conditions with is_open() after open() and fail() after operator<<().
Furthermore, prefer

while(getline(fil1, lineString))
{
  ...;
}

so you can check what line you're reading in and what is going wrong.

Happy checking...

Upvotes: 0

Related Questions