As a newbie, I could barely ever find any clear information on how to read a text file (made of space- or tab-separated numbers in columns) and store it in a 2d array to make later calculations.
I tried myself and came up with the following simple code, which actually works, and which I wanted to share here. It implements a 2d array as a vector of vectors, and fills it "on the go" while reading the file. This way, only the number of columns has to be known (say each column represents a variable), but not the amount of data. This is done through the vector::push_back() method.
I would appreciate getting some expert advice on whether it might be efficient enough for huge files and whether it is written in a "good practice" way (as is often said). Any suggestions are welcome.
#include <iostream>
#include <vector>
#include <fstream>
usingnamespace std;
#define FILENAME "array.dat"
#define COLS 2 // Number of columns in data
int main() {
// Variable declarations
fstream file;
vector < vector <int> > array; // 2d array as a vector of vectors
vector <int> rowVector(COLS); // vector to add into 'array' (represents a row)
int row = 0; // Row counter
// Read file
file.open(FILENAME, ios::in); // Open file
if (file.is_open()) { // If file has correctly opened...
// Output debug message
cout << "File correctly opened" << endl;
// Dynamically store data into array
while (file.good()) { // ... and while there are no errors,
array.push_back(rowVector); // add a new row,
for (int col=0; col<COLS; col++) {
file >> array[row][col]; // fill the row with col elements
}
row++; // Keep track of actual row
}
}
else cout << "Unable to open file" << endl;
file.close();
return 0;
}
Yes, it's written pretty well. You could possibly better leave out the #define's, and make const variables from them, which is the C++ way. Using the vector class here is fine, but for such small operations a dynamically allocated array would do.
Thank you for your thoughts, Fransje. I'll update the #defines with 'const'. Two questions:
1) I uderstand that the vector::push_back() method in this code continuously re-allocates memory to lengthen the vector size. If so, is this an efficiency issue?
2) By dynamically allocated array I understand the pointer way of implementing 2d arrays. If so, how can you generate de same code without knowing the number of rows?