Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read a 2d array from a file without knowing its length in C++?

Like the title says I'm trying to read an unknown number of integers from a file and place them in a 2d array.

#include <iostream>
#include <fstream>
using namespace std;
int main()
{

fstream f;int i,j,n,a[20][20];char ch;

i=0;j=0;n=0;
f.open("array.txt", ios::in);
while(!f.eof())
{
    i++;
    n++;
    do
    {
        f>>a[i][j];
        j++;
        f>>ch;
    }
    while(ch!='\n');
}

for(i=1;i<=n;i++)
{
    for(j=1;j<=n;j++)
        cout<<a[i][j]<<endl;
    cout<<endl;
}
return 0;

}

and my "array.txt" file :

1 1 1
2 2 2
3 3 3

After compiling the program, it prints this

enter image description here

like image 447
NacRonDX Avatar asked Dec 14 '15 18:12

NacRonDX


1 Answers

As your input file is line oriented, you should use getline (C++ equivalent or C fgets) to read a line, then an istringstream to parse the line into integers. And as you do not know a priori the size, you should use vectors, and consistently control that all lines have same size, and that the number of lines is the same as the number of columns.

Last but not least, you should test eof immediately after a read and not on beginning of loop.

Code becomes:

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int main()
{

    fstream f;
    int i=0, j=0, n=0;
    string line;
    vector<vector<int>> a;
    f.open("array.txt", ios::in);
    for(;;)
    {
        std::getline(f, line);
        if (! f) break; // test eof after read
        a.push_back(vector<int>());
        std::istringstream fline(line);
        j = 0;
        for(;;) {
            int val;
            fline >> val;
            if (!fline) break;
            a[i].push_back(val);
            j++;
        }
        i++;
        if (n == 0) n = j;
        else if (n != j) {
            cerr << "Error line " << i << " - " << j << " values instead of " << n << endl;
        }
    }
    if (i != n) {
        cerr << "Error " << i << " lines instead of " << n << endl;
    }

    for(vector<vector<int>>::const_iterator it = a.begin(); it != a.end(); it++) {
        for (vector<int>::const_iterator jt = it->begin(); jt != it->end(); jt++) {
            cout << " " << *jt;
        }
        cout << endl;
    }
    return 0;
}
like image 87
Serge Ballesta Avatar answered Sep 30 '22 10:09

Serge Ballesta