简体   繁体   中英

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.

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.

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);

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...

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM