'Creating a graph from a txt file in C

I have a txt file, which contains groups of 3 elements in each line (2 strings for vertices and 1 integer for edge), which i want to use as input to create an adjacency list for a graph.

The txt file is as so: "string1 string2 34" and the elements are separated by tabs.

I've tried for starters trying to read from the file, using fgets , and managed to print the elements, but i'm stuck as to how i can parse them and store them. Any ideas?



Solution 1:[1]

A complete solution can be found at https://www.thecrazyprogrammer.com/2017/06/bellman-ford-algorithm-in-c-and-c.html

The Bellman-Ford algorithm in C is also discussed in https://stackoverflow.com/a/36831569/18980756.

Nevertheless, some code based on your input to put the elements into a dynamically allocated linked list:

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

typedef struct FORM {
    char *vertice_one;
    char *vertice_two;
    int weight;
    struct FORM *next;
} FORM;

int main() {
    int err = 0; // error indicator

    // helper to store temporarily store read values
    char s1[256], s2[256]; 
    int w;

    FORM *firstEntry = NULL; // root element for the list

    FILE *file = fopen("forms.txt", "r");
    if (file == NULL) goto cleanup;

    // read three line elements into variables
    while (fscanf(file, "%s%s%d\n", &s1[0], &s2[0], &w) == 3) {
        // print read elements for debugging purposes
        printf("read: %s-%s-%d\n", s1, s2, w);

        // dynamically allocate memory to store the read values
        FORM *newEntry = malloc(sizeof *newEntry);
        if (newEntry == NULL) {
            fprintf(stderr, "Error - Not enough memory!");
            err = 1;
            goto cleanup;
        }

        char *vert1 = malloc(strlen(&s1[0]) + 1);
        char *vert2 = malloc(strlen(&s2[0]) + 1);
        if (vert1 == NULL || vert2 == NULL) {
            fprintf(stderr, "Error - Not enough memory!");
            err = 1;
            goto cleanup;
        }
        memcpy(vert1, &s1[0], strlen(&s1[0]) + 1);
        memcpy(vert2, &s2[0], strlen(&s2[0]) + 1);

        newEntry->vertice_one = vert1;
        newEntry->vertice_two = vert2;
        newEntry->weight = w;

        // put new entry to front a linked list
        newEntry->next = firstEntry;
        firstEntry = newEntry;
    }

    FORM *p = firstEntry;
    while(p != NULL) {
        printf("%s\t%s\t%d\n", p->vertice_one, p->vertice_two, p->weight);
        p = p->next;
    }

    FORM *q;
cleanup:
    q = firstEntry;
    while(q != NULL) {
        FORM *entry = q;
        q = q->next;
        if (entry->vertice_one != NULL) free(entry->vertice_one);
        if (entry->vertice_two != NULL) free(entry->vertice_two);
        free(entry);
    }

    if (file != NULL) {
        fclose(file);
    }

    return err;
}
$ gcc -Wall -Wextra graph.c
$ ./a.out                  
read: vert1-vert2-1
read: vert3-vert4-2
vert3   vert4   2
vert1   vert2   1
$ 

Now you are in C land and can start thinking about how you want to work with the data read.

I guess

  • FORM should be named EDGE
  • vertex_one should be named source
  • vertex_two should be named destination
  • weight remains weight

You could avoid the dynamic allocation if you define arrays which are large enough to hold the data from the file.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1