How to print a graph correctly in C

So i have this file format like this

aAa     5     bBb
bBb     3     cCc
cCc     7     dDd
dDd     2     eEe
eEe     8     fFf
fFf     4     gGg
gGg     6     hHh
hHh     1     iIi
iIi     9     jJj
jJj     5     kKk
kKk     3     lLl
lLl     7     mMm
mMm     4     nNn
nNn     6     oOo
oOo     2     pPp
pPp     8     qQq
qQq     1     rRr
rRr     9     sSs
sSs     5     tTt

where column onerepresents vertex1, column 2 represents weight, and column 3 represents vertex2 the vertex to which vertex 1 is connected to.

I have to do more but for now i just have to print this and we have to use linked lists to do it.

This is my take on the exercise

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct edge_s edge_t;
typedef struct vertex_s vertex_t;

struct edge_s {
    struct edge_s *next;
    int weight;
    vertex_t *vertex;
};

struct vertex_s {
    struct vertex_s *next;
    char *name;
    edge_t *edge;
    int traversed;
};

typedef struct graph_s {
    vertex_t *head;
    int n;
} graph_t;

vertex_t *find_vertex(graph_t *graph, const char name[20]);
void vertex_add(graph_t *graph, const char *name);
void edge_add(graph_t *graph, vertex_t *vertex1, vertex_t *vertex2, int weight);
graph_t *graph_init(void);
graph_t *fileread(const char *name);
void graph_write(graph_t *graph);

graph_t *graph_init() {
    graph_t *graph = malloc(sizeof(graph_t));
    if (graph == NULL)
        exit(EXIT_FAILURE);
    graph->head = NULL;
    graph->n = 0;

    return graph;
}

void edge_add(graph_t *graph, vertex_t *vertex1, vertex_t *vertex2, int weight) {
    edge_t *edge = malloc(sizeof(edge_t));
    if (edge == NULL)
        exit(EXIT_FAILURE);
    edge->weight = weight;
    edge->vertex = vertex2;
    edge->next = vertex1->edge;
    vertex1->edge = edge;
}

void vertex_add(graph_t *graph, const char *name) {
    vertex_t *vertex = malloc(sizeof(vertex_t));
    if (vertex == NULL)
        exit(EXIT_FAILURE);
    vertex->edge = NULL;
    vertex->traversed = 0;
    vertex->name = strdup(name);
    vertex->next = graph->head;
    graph->head = vertex;
}

vertex_t *find_vertex(graph_t *graph, const char name[20]) {
    vertex_t *v = graph->head;
    while (v != NULL) {
        if (strcmp(v->name, name) == 0)
            return v;
        v = v->next;
    }
    return NULL;
}

graph_t *fileread(const char *name) {
    FILE *fp = fopen(name, "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);

    graph_t *graph = graph_init();
    int weight;
    char name1[20], name2[20];
    vertex_t *vertex1, *vertex2;

    while (fscanf(fp, "%s %d %s", name1, &weight, name2) != EOF) {
        vertex1 = find_vertex(graph, name1);
        if (vertex1 == NULL) {
            vertex_add(graph, name1);
            vertex1 = graph->head; 
        }

        vertex2 = find_vertex(graph, name2);
        if (vertex2 == NULL) {
            vertex_add(graph, name2);
            vertex2 = graph->head; 
        }

        edge_add(graph, vertex1, vertex2, weight);
    }


    fclose(fp);
    return graph;
}

void graph_write(graph_t *graph) {
    vertex_t *vertex = graph->head;
    edge_t *edge;

    while (vertex != NULL) {
        printf("%s->", vertex->name);
        edge = vertex->edge;
        while (edge != NULL) {
            printf(" %d -> %s", edge->weight, edge->vertex->name);
            edge = edge->next;
        }
        printf("\n");
        vertex = vertex->next;
    }
}

int main() {
    graph_t *graph = fileread("file");
    graph_write(graph);
    return 0;
}

The functions you can guess their meaning by the names so i doubt i need to explain much but if you question the not used variables in the structures its because its for the 2nd part of the exercise which i will solve after i print this.

Thing is when i print the exercise it shows this

tTt->
sSs-> 5 -> tTt
rRr-> 9 -> sSs
qQq-> 1 -> rRr
pPp-> 8 -> qQq
oOo-> 2 -> pPp
nNn-> 6 -> oOo
mMm-> 4 -> nNn
lLl-> 7 -> mMm
kKk-> 3 -> lLl
jJj-> 5 -> kKk
iIi-> 9 -> jJj
hHh-> 1 -> iIi
gGg-> 6 -> hHh
fFf-> 4 -> gGg
eEe-> 8 -> fFf
dDd-> 2 -> eEe
cCc-> 7 -> dDd
bBb-> 3 -> cCc
aAa-> 5 -> bBb

Which is mostly correct but the first row. The first row should not be there. Any idea on how to fix it?

  • 1

    wow.. AMAZING. Apparently tTt is simply not connected to anything. Its not a print error. The code is correct as it is

    – 

  • If you change the line while (fscanf(fp, "%s %d %s", name1, &weight, name2) != EOF) { to while (fscanf(fp, "%s %d %s", name1, &weight, name2) == 3) {, does the bug disappear?

    – 




  • @AndreasWenzel Its not a bug. The code is correct. i asked chat gdp to come up with a txt file cuz i was too lazy to write it myself (i have picture slides so i cant copy paste) and didnt realize that the last node simply wasnt connected to anything

    – 

If you search for tTt

enter image description here

in your input you will see that tTt has only ingoing vertex, hence your output looks good from the perspective of tTt. Of course, you might decide not to output items only having outgoing vertex, so in your

    while (vertex != NULL) {
        printf("%s->", vertex->name);
        edge = vertex->edge;
        while (edge != NULL) {
            printf(" %d -> %s", edge->weight, edge->vertex->name);
            edge = edge->next;
        }
        printf("\n");
        vertex = vertex->next;
    }

instead of printf‘ing your node, you can do the printf only when you realized there is something to point to. But this seems to be optional and your code seems to be good as it is.

In graph_write, check to see if edge is NULL before printing the vertex name and ->. If the vertex doesn’t lead anywhere, there’s no need to print anything.

void graph_write(graph_t *graph) {
    vertex_t *vertex = graph->head;
    edge_t *edge;

    while (vertex != NULL) {
        edge = vertex->edge;

        if (edge != NULL) {
            printf("%s->", vertex->name);

            while (edge != NULL) {
                printf(" %d -> %s", edge->weight, edge->vertex->name);
                edge = edge->next;
            }
            printf("\n");
        }

        vertex = vertex->next;
    }
}

Leave a Comment