You need to analyze your source file and then do input operations as needed.
The adjency matrix seems to be for a directed and weighted graph. It is not clear to me, if it is row or column oriented, but this is not important for the reding operation.
So, would do we see?
- The dimension as an unsigned interger number on its own line
- It follows a rectangular matrix with the above given dimension. The rows are given as comma separated values. This, we call CSV. And, there are many many ways to split a csv into its components: BecaUse the matrix is quadratic, there will be dimension rows.
- At the end, we have and additionalline, containing 2 values, the start coordinates, separated by a comma.
Deriving from that observations, we will decide how to read.
The first line can be simply read, with a standard formatted input function, using the extractor operator >>. Formatted input
will alwaystry toconvert the input data, until it sees a white space (including the newline character '\n'). It will not consume the white space, so the '\n').
The next lines could be written as a whole line using the std::getline
(unformatted input) function. But caveat. std::getline
will read, until it finds a newline '\n'. And remember from above, there is still a newline character in theinput stream. So,if you would simply call std::getline
, it would read an empty string and then consume the new line character. To solve this, we can simply use the std::ws function. This will consume, but not read, all white spaces in front of a text. So, we can always write: std::getline(file >> std::ws, data);
This will first call file >> std::ws
and then invoke std::getline
.
Ok, this theory should be clear now.
Then, we need to create a 2 dimensional array. You are just creating a one dimensional array. This can be done by first creating an array for the rows, and then, for each row, additional arrays for the columns. This wecould do like the below:
// allocate memory for rows
int** matrix = new int* [dimension];
// For each row, allocate memory for the columns
for(unsigned int row=0; row < dimension; ++row)
matrix[row] = new int [dimension];
Now we have a 2d array, which we can address with matrix[row][col];
Next, because we do know the dimension, we can create a loop and call std::getline
dimension times.
After having read one line, we need to split that line and store the values. For that we will use one common approach, by using an std::istringstream
and std::getline
until we see a comma.
At the end, we read the last line and extract the start coordinates in the same way.
For every read operation an error check should be added.
Then an example program could looklike below.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
int main() {
// Open the file
std::ifstream fileStream{ "r:\\text2a.txt" };
// Check, if we could open the file
if (fileStream) {
// Read the dimension of the matrix and check for valid input
unsigned int dimension{};
if ((fileStream >> dimension) and (dimension > 0)) {
// Now we haveopened the file and read the dimension
// Allocate array. Firs,allocate memory for rows
int** matrix = new int* [dimension];
// And now, for each row, allocate space for columns
// Then read the rows with the column values
for (unsigned int row = 0; row < dimension; ++row) {
matrix[row] = new int[dimension] {};
// Read next line from file
std::string line{};
if (std::getline(fileStream >> std::ws, line)) {
// Put the line into an std::istringstream, so that we can extract the column values
std::istringstream iss(line);
// Extract all columns
for (unsigned int col = 0; col < dimension; ++col) {
std::string valueAsString{};
if (std::getline(iss, valueAsString, ',')) {
matrix[row][col] = std::stoi(valueAsString);
}
else {
// Could not read column value. Show error message
std::cerr << "\n\n*** Error. Could not read value at row " << row << ", column: "<< col << "\n\n";
}
}
}
else {
// Could not read row with column values
std::cerr << "\n\n*** Error. Could not read row number " << row << "\n\n";
}
}
// Now we have read the matrix.
// Get the start point
unsigned int rowStart{}, columnStart{};
char comma{};
if ((fileStream >> rowStart >> comma >> columnStart) and comma == ',') {
// Now, we have all data
// Show some debug output
std::cout << "Adjancency matrix\n\nDimension: " << dimension << "\n\nMatrix:\n\n";
for (unsigned int row = 0; row < dimension; ++row) {
for (unsigned int col = 0; col < dimension; ++col) {
std::cout << matrix[row][col] << ' ';
}
std::cout << '\n';
}
std::cout << "\n\nStart point: " << rowStart << ", " << columnStart << '\n';
// Release all allocated memory
for (unsigned int row = 0; row < dimension; ++row)
delete[] matrix[row];
delete[] matrix;
}
else {
// Could not read start values
std::cerr << "\n\nError: Could not read start values\n\n";
}
}
else {
// Invalid input for dimension of adjacency matrix. Show error message
std::cerr << "\n\n*** Error. Invalid dimentsion found\n\n";
}
}
else {
// File could not be opened. Show error message
std::cerr << "\n\n*** Error. Could not open source file\n\n";
}
}