I have a text file structured like this:
6
0,2,0,0,5,0
3,0,4,0,0,0
0,0,0,6,1,0
0,0,0,0,2,0
0,0,0,0,2,4
1,0,0,0,0,0
0,5
The first number represents the number of vertices and the 2D matrix is an adjacency matrix. The last line contains start and end points. I understand how to use the data and what its purpose is; what I'm struggling with is properly reading the data so I can process it. I currently have this:
void directedGraphAnalysis() {
//Open file, read contents, write to graph
ifstream file("test2a.txt");
string data = ""; //Each line will be read as a string and converted to an int
int nodeCount = 0;
int* matrix = nullptr;
int matrixIndex = 0;
int count = 0;
int v1 = INT_MAX;
int v2 = INT_MAX;
while (getline(file, data, ',')){
int x = stoi(data);
++count;
if (count == 1) {
nodeCount = x;
matrix = new int[nodeCount * nodeCount];
}
else if (count < (nodeCount * nodeCount) - 1) {
matrix[matrixIndex++] = x;
}
else if (v1 == INT_MAX) {
v1 = x;
}
else {
v2 = x;
}
cout << "X: " << x << endl;
}
//DirectedGraph graph = DirectedGraph(matrix, nodeCount);
//graph.displayGraph();
cout << "ANALYSIS COMPLETE." << endl;
}
This implementation seems to get the node count right but every line after that skips the first digit, meaning v1 and v2 are never set and the matrix has incorrect edges that don't match with the text file. Matrix is simply a 1D array representing a 2D matrix of size nodeCount * nodeCount. I'm not sure what it is I'm doing that's causing the matrix to be improperly filled, nor do I know why the first digits are being skipped.
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?
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 inputwill 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::getlinewill 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 callstd::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 callfile >> std::wsand then invokestd::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:
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::getlinedimension 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::istringstreamandstd::getlineuntil 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.