let's say we have a matrix in a matrix.txt file, stored like this:
and we want to transform it into:
Number 8 (first number) means how big will 2D array be. After that it means: 1 is connected to 2 (value of connection is 1, it will always be 1) 1 is connected to 8 3 is connected to 4
And when transformed into 2D dynamical array, we want the value 1 in ARRRAY 0,1...0,7...2,3 and soo on (i didnt use square brackets because stackoverflow read them as links).
int number;
int **a = new int*[number];
for (int i = 0; i<number; i++) {
a[i] = new int[number];
}
for (int i = 0; i<number; i++) {
delete[]a[i];
}
delete[]a;
string line;
ifstream myfile("matrix.txt");
if (myfile.is_open())
{
getline(myfile, line);
istringstream(line)>> number;
while (getline(myfile, line)){
cout << line << '\n';
//HERE I SHOULD TURN THOSE NUMBERS INTO VALUES IN 2D ARRAY
}
myfile.close();
}
So my question is: How do i turn this numbers into matrix in 2d array?
Thank you
The easy way, but possibly not the fastest way, is to write the line into a std::stringstream, then read back out of the stringstream into row, column, and value variables. If you are reading from a file the cost of reading the file in the first place usually dwarfs the cost of parsing the file the slow way. If it matters in your case (and profile the code first to make sure it does) look into manually parsing the file. That said, this basic logic will hold.
while (getline(myfile, line)){
cout << line << '\n';
std::stringstream linestream(line);
int row;
int column;
int value;
if (linestream >> row >> column >> value)
{
a[row-1][column-1] = value;
a[column-1][row-1] = value;// mirror
}
else
{
// handle file formatting error
}
}
Off topic, consider using a matrix class to manage a for you rather than a raw 2D Array. The matrix class here at isocppp.org is good and fast, as well as wrapped in some very good general-purpose advice.
The above code with the isocpp matrix looks like:
while (getline(myfile, line)){
cout << line << '\n';
std::stringstream linestream(line);
int row;
int column;
int value;
if (linestream >> row >> column >> value)
{
a(row-1,column-1) = value;
a(column-1,row-1) = value;// mirror
}
else
{
// handle file formatting error
}
}
Nearly identical and a lot easier to use because you don't have to worry about managing the memory yourself, passing the array dimensions around, or a bit of bad code (such as a[4] = 0;
) nuking a row of your array.
This code
int number;
int **a = new int*[number];
for (int i = 0; i<number; i++) {
a[i] = new int[number];
}
for (int i = 0; i<number; i++) {
delete[]a[i];
}
delete[]a;
has two serious problems:
a
is sized with number
, and number
hasn't been assigned yet. number
could be anything from an instantly fatal negative number (can't have an array with a negative size) to a potentially fatal huge number (Your computer have 9,223,372,036,854,775,807 squared bytes of RAM? Didn't think so.)So:
// define `a` here
string line;
ifstream myfile("matrix.txt");
if (myfile.is_open())
{
getline(myfile, line);
istringstream(line)>> number;
// allocate storage for `a` here
while (getline(myfile, line)){
cout << line << '\n';
//line reading code goes here
}
myfile.close();
}
// delete `a` somewhere down here after it's been used.