I have a .txt file of numbers (in this case all less than 100) separated by spaces, in rows separated by new lines. Something like this:
41 53 07 91 44
52 17 13 03 21
I would like to read these numbers into a 2d array, exactly as they appear, so that spaces separate columns of the array, and new lines separate rows.
I can get it to read the lines in as strings, but then I'm having trouble separating out individual numbers, and getting it to treat them as integers.
Try this:
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
int main()
{
// The result of the read is placed in here
// In C++, we use a vector like an array but vectors can dynamically grow
// as required when we get more data.
std::vector<std::vector<int> > data;
// Replace 'Plop' with your file name.
std::ifstream file("Plop");
std::string line;
// Read one line at a time into the variable line:
while(std::getline(file, line))
{
std::vector<int> lineData;
std::stringstream lineStream(line);
int value;
// Read an integer at a time from the line
while(lineStream >> value)
{
// Add the integers from a line to a 1D array (vector)
lineData.push_back(value);
}
// When all the integers have been read, add the 1D array
// into a 2D array (as one line in the 2D array)
data.push_back(lineData);
}
}
Ok, the "exactly as they appear" requirement means that you need a ragged array, in case different number of columns appear in different rows. I would use std::vector< std::vector<long> >
. Each contained vector corresponds to one row.
So, each time you read a row of text, create a new empty vector.
Call strtol
repeatedly on the row you read, using push_back
to collect them into the vector. When the output pointer is the same as the input pointer (this indicates failure, probably because you reached the end of the line), push_back
the whole vector and start the next row.
Something like this:
std::vector< std::vector<long> > all_data;
std::string text_row;
while(getline(fin, text_row)) {
all_data.push_back();
std::vector<long>& this_row = *all_data.rend();
const char* p1 = text_row.c_str();
const char* p2;
while (1) {
long num = strtol(p2 = p1, &p1, 0);
if (p1 == p2) break;
this_row.push_back(num);
}
/* to ignore blank lines, add this code
if (this_row.empty()) all_data.pop_back();
*/
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With