2

I'm making a program that reads multiple structs in and out of different files. For one of them, I have a format for reading from the file, and one for writing to it.

#include <stdio.h>

int main() {
    const char* MATERIA_FORMAT_IN = "(DPAAIN.%03d;%[^;];%.2f;%.2f;%[^)])";

    int id = 0;
    char nome[50] = { '\0' }, status = { '\0' };
    float nota1 = 0.0, nota2 = 0.0;

    sscanf("(DPAAIN.001;Algoritmos e Técnicas de Programação I;10.00;10.00;CONCLUÍDA)", MATERIA_FORMAT_IN, &id, nome, &nota1, &nota2, status);
        
    return 0;
}

This reads successfully into id and nome, but all other variables don't get the values I want them to get. In a scenario where this works, I want id, nome, nota1, nota2 and status to have the values of 1, "Algoritmos e Técnicas de Programação I", 10.00, 10.00 and "CONCLUÍDA", respectively.

I don't know what to try. (I think) the specifiers are right, the amount of arguments for each specifier is right, I don't know what's messing up my fscanf() (in the example above, sscanf(), and why only for this struct, seen as I did three different ones before this, including the one I wrote the logic for the first time for, and they all worked with %[^;]. I don't know what the problem is. I know the problem is in the formatter, but I don't know what else to try.

I've tried rewriting that specifier, thought maybe I had a weird character in there. Didn't work. Something is making this specifier mess up all the ones after it.

1
  • 1
    Is it important that the string scanned ends with a ')'? Code's sscanf() call lacks detecting if it exists. Commented Jul 31 at 4:10

1 Answer 1

5

The code demonstrates a few errors.

  1. but all other variables don't get the values I want them to get.

    The returned value of *scanf() should be checked instead of testing if values of variables are modified.

  2. Unlike printf, *scanf() functions do not support precision. %.2f should be the simple %f, or with the value length %5f (10.00 consists of 5 characters).

  3. char nome[50] = { '\0' }, status = { '\0' };
    

    is the same as

    char nome[50] = { '\0' };
    char status = '\0';
    

    You likely wished

    char nome[50] = { '\0' }, status[50] = { '\0' };
    

The working code: https://godbolt.org/z/1j5xGcbxM

Sign up to request clarification or add additional context in comments.

3 Comments

status not being an array was an oversight on my part when creating the MRE, my code doesn't have that issue. If I may ask, why should I check for the value returned by *scanf() and not if the values are modified? From my understanding, *scanf() returns the amount of values read, so it would be the same as checking the variables, no?
If you do that, there's no way to tell the difference between the value not being read, and whether the value being read is the same as the default (assuming the variable was initialized).
That makes sense. Thanks for the clarification.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.