Search code examples
cstructurescanffgetc

Issue with reading a file and saving values on structure


This is part of a project that i'm doing. Essentially i want to read a text file called "Circuit" that has this inside:

Circuit title example

V1 1 0 24

V2 3 0 15

R1 1 2 10000

R2 2 3 8100

R3 2 0 4700

To give you some context, the values represent a circuit like this: Circuit example I made a code to save all these values in a structure and printed them out to see if they were being saved correctly.

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

    typedef struct
    {
char type, name, noMaior, noMenor;
int value;
    }line;

    int main(void)
    {
line ramo[10];
FILE *ficheiro;
int i = 0, j;
char titulo[200];

if ((ficheiro = fopen("circuit.txt", "r")) == NULL)
    printf("Error opening file!");

fgets(titulo, 199, ficheiro);
    printf("%s", titulo);

while ((fscanf(ficheiro, "%c%c %c %c %d\n", &ramo[i].type, &ramo[i].name, &ramo[i].noMaior, &ramo[i].noMenor, &ramo[i].value)) != EOF) 
    {
        i++;
        //if (fgetc(ficheiro)=='.')
        //  break;  
    }
    fclose(ficheiro);

for (j = 0; j < i; j++)
    printf("%c%c %c %c %d\n", ramo[j].type, ramo[j].name, ramo[j].noMaior, ramo[j].noMenor, ramo[j].value);

return 0;

}

It outputs the same text that is in the file, which is what i intended. Now here comes the tricky part, we have to put ".end" or ".END" in the end of our file, so i made those two commented lines to scan the file for a dot and stop reading it if it encounters one but it causes me some problems when saving the values to the structure. This is what i get as an output:

Circuit title example

V1 1 0 24

2 3 0 15

1 1 2 10000

2 2 3 8100

3 2 0 4700

The "break" works as intended, because if i put a dot in the middle of the file it will stop reading whatever comes after but sadly it is ignoring the first letter and according to the debug tool it is saving a ' ' (a space) in the place of the letters (ramo[].type). I tried to learn as much as i could about the behaviours of fscanf and fgetc but i can't draw any conclusion as to why this is happening.

PS: tried to translate some of the variables to make it easier to read but some are still in portuguese, like "ficheiro"=file. Also take it easy on me folks, i just started learning coding!


Solution

  • Use fgets to read each line from the file. Then you can check for a dot or use strncmp or strcmp to test for specific values. If the value is not detected, parse the line using sscanf.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct
    {
        char type, name, noMaior, noMenor;
        int value;
    }line;
    
    int main(void)
    {
        line ramo[10];
        FILE *ficheiro;
        int i = 0, j;
        char titulo[200];
        char input[200];
    
        if ((ficheiro = fopen("circuit.txt", "r")) == NULL)
            printf("Error opening file!");
    
        fgets(titulo, sizeof titulo, ficheiro);
        printf("%s", titulo);
    
        while ( fgets ( input, sizeof input, ficheiro)) 
        {
            if ( '.' == input[0]) {//test for a dot at start of line
                break;
            }
            else {
                if (( 5 == sscanf(input, "%c%c %c %c %d"
                , &ramo[i].type, &ramo[i].name, &ramo[i].noMaior, &ramo[i].noMenor, &ramo[i].value))) {
                    i++;
                }
            }
        }
        fclose(ficheiro);
    
        for (j = 0; j < i; j++)
            printf("%c%c %c %c %d\n", ramo[j].type, ramo[j].name, ramo[j].noMaior, ramo[j].noMenor, ramo[j].value);
    
        return 0;
    }