0

I'm trying to read a graph file (.gr) with fscanf in the code below

#include<stdio.h> 

int main( int argc, char** argv) 
{
    FILE *fp;
    static char *input_file_name;
    int size, edges, source, target, weight;

    printf("Reading Graph File\n");
    printf("argc=%d\n", argc);

    if (argc == 2 ) 
    {
        input_file_name = argv[1];
        printf("Input file: %s\n", input_file_name);
    }
    else 
    {
        input_file_name = "../beleg/resources/sampleGraph-1.gr";
        printf("No input file specified, defaulting to %s\n", input_file_name);
    }

    //Read in Graph from a file
    fp = fopen(input_file_name,"r");
    if(!fp)
        printf("Error Reading Graph File\n");

    while (!feof(fp)) 
    {
        if(fscanf(fp, "%*s %*s %d %d", &size, &edges))
            printf("(first line) size=%d edges=%d\n", size, edges);

        if(fscanf(fp, "%*s %d %d %d ", &source, &target, &weight))
            printf("arc from %d to %d weight %d\n", source, target, weight); 
    }

    return 0; 
} 

Here is a sample graph file, with p=init size, c=comment and a=arc

p sp 6 9
c graph contains 6 nodes and 9 arcs
c
a 1 2 7
a 1 3 9
a 1 6 14
c
a 2 3 10
a 2 4 15
c
a 3 4 11
a 3 6 2
c
a 4 5 6
c
a 5 6 9
c
a 6 5 16

The goal is to retrieve the init line and all arc lines like this:

...
(first line) size=6 edges=9
arc from 1 to 2 weight 7
arc from 1 to 3 weight 9
arc from 1 to 6 weight 14
...
arc from 6 to 5 weight 16

However the real output is:

...
(first line) size=6 edges=9
arc from 22050 to 1852102336 weight 22050
(first line) size=6 edges=9
arc from 22050 to 1852102336 weight 22050
arc from 22050 to 1852102336 weight 22050
(first line) size=1 edges=2
arc from 22050 to 1852102336 weight 22050
(first line) size=3 edges=9
arc from 1 to 6 weight 14
(first line) size=2 edges=3
arc from 1 to 6 weight 14
(first line) size=4 edges=15
arc from 1 to 6 weight 14
(first line) size=4 edges=11
arc from 3 to 6 weight 2
(first line) size=4 edges=5
arc from 3 to 6 weight 2
(first line) size=5 edges=6
arc from 3 to 6 weight 2
(first line) size=6 edges=5
arc from 3 to 6 weight 2
  1. I'd like to understand why there is this difference between expectation and real result.
  2. And then how to fix the code to get only init and arc lines.
Frumda Grayforce
  • 119
  • 1
  • 13
  • 5
    Did you mean to have a semi-colon at the end of this line? `if(fscanf(fp, "%*s %d %d %d ", &source, &target, &weight) );` – john Jul 07 '20 at 13:18
  • 2
    `if(fscanf(...))` -> `if(fscanf(...) == 2)` `fscanf` returns the number of items successfully scanned. – KamilCuk Jul 07 '20 at 13:19
  • 1
    Do you intend this to be C or C++? – Beta Jul 07 '20 at 13:22
  • @KamiCuk that means I put if(fscanf(...) == 2) for my init line and ==3 for my arcs, right? If so it doesn't work. – Frumda Grayforce Jul 07 '20 at 13:25
  • 2
    You are calling `fscanf` twice in your loop, and I guess you are assuming that if the first one fails, the second will try to re-scan the same input line. That is not the case, a failed `fscanf` can partially consume the input, messing with the next `fscanf` calls. You need to rework your logic completely. – chi Jul 07 '20 at 13:25
  • @Beta Well currently it's C++. But really I was thinking it will work out the same way in C. – Frumda Grayforce Jul 07 '20 at 13:26
  • 3
    [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – molbdnilo Jul 07 '20 at 13:41
  • You might find the C++ style of file I/O more handy. – Beta Jul 08 '20 at 03:57

0 Answers0