简体   繁体   中英

Reading input from file and populating array to store data for later use

I'm trying to make multiple arrays of maximum size 10 that hold the contents of an input file. Suppose the file is formatted like:

1 3 2 4 0 5 8 -3
3 1 4 6 0 3
4 83 2 12 1 3
4 30 4 -2

Where each line cannot exceed more than 10 integers.

void read_input(ifstream &file)
{
    vector<array<int, 10> > main_array;

    while(!(file.eof()))
    {
        int idx = 0;
        string values;
        array<int, 10> part_array;

        getline(file, values);
        istringstream inStream;
        inStream.str(values);

        while((inStream >> part_array[idx++]).good() == true);
        main_array.push_back(part_array);

        file.ignore();
    }

    for(auto it = main_array.begin(); it != main_array.end(); it++)
    {
        for(auto& s: *it)
        {
            cout << s <<  " ";
        }
        cout << "\n";
    }
}

This gives me the output:

1 3 2 4 0 5 8 -3 0 6164240
1 4 6 0 3 5 8 -3 0 6164240
83 2 12 1 3 5 8 -3 0 6164240
30 4 -2 1 3 5 8 -3 0 6164240

Which is clearly wrong. I know this may have to do with me iterating over array elements that aren't initialized, but how can I avoid this error? Just as a note, it is essentially that I use arrays to hold the values at each line in the file. That is, one array must handle the integers in the first line; another in the second line...

You can use

 vector<vector<int> > main_array;

instead of an array - then just read items from input and push them (push_back) into the "inner" vector - this way you won't have uninitialized array elements at the end in case when data row is shorter than 10 elements.

Full solution may look like this (I've kept some parts of your original code for consistency):

using namespace std;

void read_input(ifstream &file)
{
    vector<vector<int> > main_array;

    string line;    //buffer for single line read from file 
    // reading part
    while(getline(file, line))
    {       
        stringstream inStream(line);
        vector<int> row;    //single row buffer
        int val = 0;
        while(inStream >> val)
        {
            row.push_back(val);
        }       
        main_array.push_back(row);
    }   

    //display part
    for(auto it = main_array.begin(), end = main_array.end(); it != end; ++it)
    {
        for(auto& s: *it)
        {
            cout << s <<  " ";
        }
        cout << "\n";
    }
}

Use this if you find it useful,

void readData(ifstream &inf)
{
    string str;
    vector<vector<int>> intArr;

    while (getline(inf, str))
    {
        stringstream ss(str);
        int i;
        vector<int> a;
        while (ss >> i)
        {
            a.push_back(i);
        }
        intArr.push_back(a);
    }
}

You shouldn't use eof() to check end of file.

std::array is a container that encapsulates constant size arrays., so by declaring with array<int, 10> there are already 10 integers in the array. You need to use vector instead, and change your loop

 while((inStream >> part_array[idx++]).good() == true);

to

 bool good = true;
 while(idx <10 ) {
     int v;
     if(!(inStream >> v).good() ) break;
     idx++;
     part_array.push_back(v); //now a vector
 }

You have used an array with 10 elements but you know there may be fewer than ten items. It would be better to use a vector, and push_back what you have.

Aside from that, there are a variety of potential problems with the code. If you send it a bad ifstream it gets stuck in a loop.

while(!(file.eof())) is asking for trouble.

Next, file.ignore(); then ignores the first items of each line. If you change to use a vector of vectors as people have said, use while(getline(file, values)) instead of using the eof check and remove the ignore it should work.

Change this line

array<int, 10> part_array;

to

array<int, 10> part_array = {};

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