-1

I am trying to print a matrix representing Graph nodes and edge weights using for loops. All rows after the first one work as expected, but the print of the Node names of columns is behaving very strange, I am completely lost after trying multiple different methods. Here is the 'bugged' code and output.

Code:

void Graph::print_graph_matrix(void)
{
    std::cout << "\n";

    int i, j;

    for(i = 0; i < nodes.size(); i++)
    { 
        std::cout << "\t" << nodes[i];
    }

    std::cout << "\n";

    for(i = 0; i < nodes.size(); i++)
    {
        std::cout << nodes[i];

        for(j = 0; j < nodes.size(); j++)
        {
            std::cout << "\t" << edges[i][j];
        }

        std::cout << "\n";
    }
}

Output:

        D
A       0        0        0        0
B       0        0        0        0
C       0        0        0        0
D       0        0        0        0

However the top column labels should print

A        B        C        D

When I tried debugging it within the code (by printing out the value of i itself), the first time i printed out it printed out as 3, instead of 0, my target starting index.

I've never seen anything like this, please help me understand what is going on here. Thank you!

EDIT: Other parts of my code are being asked for as this may be happening elsewhere.

Main:

int main()
{
clear_screen();

int graph_num;
std::string filename;

std::cout << "How many graphs would you like to create?\n";
std::cin >> graph_num;
std::cin.ignore();

std::fstream files[graph_num];
Graph * graphs[graph_num];

for(int k = 0; k < graph_num; k++)
{
    graphs[k] = new Graph();

    std::cout << "\nEnter the name of file " << k+1 << " to read: ";
    std::cin >> filename;
    std::cin.ignore();

    files[k].open(filename.c_str());

    if(files[k].fail())
    {
        std::cout << "\nError opening file '" << filename << "'...\n";

        return -1;
    }
    else
    {
        std::cout << "\nSuccess opening '" << filename << "'!\nSetting graph...\n";
        graphs[k]->set_graph(files[k]);
        graphs[k]->print_graph_matrix();
    }
}

for(int j = 0; j < graph_num; j++)
{
    files[j].close();
}
}

set_graph function:

void Graph::set_graph(std::fstream &fin)
{
std::string line;
std::vector<int> row;

while(getline(fin, line))
{
    if(isBlank_str(line))
    {
        std::cout << "Nodes read in successfully!\n";
        break;
    }
    else
    {
        nodes.push_back(line);
        node_num++;
    }
}

while(getline(fin, line))
{
    //set edges here
    edge_num++;

    if(fin.eof())
        break;
}

//initialize an empty row
for(int i = 0; i < node_num; i++)
{
    row.push_back(0);
}

//push back empty rows
for(int j = 0; j < node_num; j++)
{
    edges.push_back(row);
}
}

Example data file (provided by professor):

A
B
C
D

A B 3
A C 10
A D 12
B C 1
B D 14
C D 4

I know this code is somewhat sloppy as it is just the beginning of my project, but I always tend to get caught up on every bug I encounter until I can fix it. And I have never seen anything like this so I appreciate yall's time and help!

Sc00by
  • 11
  • 6
  • 1
    Can you post a minimal example we can use to compile and run this program and reproduce this error? I suspect the issue may be elsewhere. (Also, in C++, it's considered better to declare your variables inside the for loops instead of outside, since that makes it much harder to accidentally use uninitialized variables.) – templatetypedef Oct 18 '17 at 02:23
  • 7-9 lines are the same with 14-16 lines print the same variables... Maybe the problem cause by some other reasons? – ghchoi Oct 18 '17 at 02:35
  • Was this output taken from a console/terminal? – n. m. could be an AI Oct 18 '17 at 04:06
  • yes it was from the terminal, sorry for the late response. – Sc00by Oct 18 '17 at 17:16
  • Yes I am on a linux system, not sure where the files were created because the professor provided the data files. How does this relate to the index error that is happening? – Sc00by Oct 18 '17 at 21:21
  • Maybe you can check your input file using `vi`'s `:set list` to check for hidden characters, like suggested in this [answer](https://stackoverflow.com/a/3860537/2964487). – Banan Oct 18 '17 at 21:35
  • using that i find every line of the data file has ^M, EXCEPT for the last one 'C D 4'. What could this effect? – Sc00by Oct 18 '17 at 21:49
  • I think this is a carriage return (`\r`), as @n.m. hinted at in his comment. I guess it means the file was made on an old Mac OS (as according to this [answer](https://stackoverflow.com/a/1279802/2964487)). See if you can replace them with newline, or maybe try to write the file yourself manually, e.g. using `vi`. – Banan Oct 18 '17 at 22:25

3 Answers3

1

@n.m. suggested I check for '\r' characters in the input data files, and as he predicted, there indeed were these characters sitting in my strings within my vectors, which caused glitchy, overwritten output to the terminal.

To combat this I added the line:

line.erase(line.size() - 1);

And then it worked perfectly!

Sc00by
  • 11
  • 6
0

I recreated a simple sample of your program above such as this:

#include <vector>
#include <iostream>
#include <iomanip>

class Graph {
public:
    std::vector<char> nodes { 'A', 'B', 'C', 'D' };
    unsigned edges[4][4] { { 00, 01, 02, 03 },
                           { 10, 11, 12, 13 },
                           { 20, 21, 22, 23 },
                           { 30, 31, 32, 33 } };

    void print_graph();
};

void Graph::print_graph() {
    std::cout << "\n";

    unsigned i, j;

    for ( i = 0; i < nodes.size(); i++ ) {
        std::cout << "\t" << std::setw(2) << nodes[i];
    }

    std::cout << "\n";

    for ( i = 0; i < nodes.size(); i++ ) {
        std::cout << nodes[i];

        for ( j = 0; j < nodes.size(); j++ ) {
            std::cout << "\t" << std::setfill( '0' ) << std::setw(2) << edges[i][j];
        }
        std::cout << "\n";
    }    
}

int main() {
    Graph g;
    g.print_graph();

    return 0;
}

And I get the following output to the console:

     A     B     C    D
A   00    01    02   03
B   10    11    12   13
C   20    21    22   23
D   30    31    32   33

From what I can tell by the code you supplied; there should be no bug(s). This bug is more than likely coming from somewhere outside of what you have shown. The only difference with my output display is that I used std::setw() & std::setfill() for alignment to the console.

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
  • "I cannot reproduce your bug" is not an answer. – n. m. could be an AI Oct 18 '17 at 05:05
  • @n.m. I was basically showing the `OP` that the above should work and that the code they have supplied is not causing the bug and that it is coming from somewhere else. – Francis Cugler Oct 18 '17 at 09:18
  • I use a Graph header with the class definition. i can post my main, as I am new to this site, where should I go about posting my main? – Sc00by Oct 18 '17 at 17:17
  • @Sc00by You can edit your original question. Just make a note of the edit, what you changed & why you changed it. Not so much for me, but for other readers. – Francis Cugler Oct 18 '17 at 21:02
0

One culprit not mentioned:

j < nodes.size()

should be

j < edges[i].size()
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138