cfilescanf

Problem with sscanf not reading the 3 variables i want in C


I have an file containing

323,John of Sea,11.2

I want to read this and then split it on , into 3 variables: int number1 / char Name[100] / float number2. So I wrote this program:

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

int main()
{
    int number1;
    float number2;
    char Name[100],Phrase[100];
    FILE *inf ;
    
    if((inf = fopen("Information.txt","r")) == NULL){
        perror("Information.txt");
        return EXIT_FAILURE;
    }
    
    while (fgets(Phrase,100,inf) != NULL )
    {   
        sscanf(Phrase , "%d,%s,%f", &number1 , Name, &number2 ); 
        printf("%d  %s  %f \n", number1, Name, number2);   
    }
    
}

The result I get is 323 John 0.000000. I wanted 323 John of Sea 11.2.

What am I doing wrong?


Addendum: minimal reproducible example:

#include <stdio.h>

int main()
{
    int number1;
    float number2;
    char Name[100];

    sscanf("323,John of Sea,11.2\n", "%d,%s,%f", &number1, Name, &number2);
    printf("%d  %s  %f \n", number1, Name, number2);
}

Solution

  • The problem is that the %s scanf format specifier will only match a single word of input. Therefore, instead of matching John of Sea, it will only match John and leave of Sea on the input stream.

    If you want to read all characters up to (but not including) the comma, then you should use %[^,] instead of %s.

    Also, you should always check the return value of scanf to verify that it was able to match all 3 arguments, before attempting to use these arguments.

    Additionally, I recommend to limit the number of characters written to Name, so that if the input is too large to fit into Name, no buffer overflow will occur (which may cause your program to crash). Since Name has a size of 100 characters, it has room for 99 normal characters plus the terminating null character. Therefore, I recommend to limit the number of matched characters to 99, by using %99[^,] instead of %[^,].

    For the reasons stated above, I recommend that you change

    sscanf(Phrase , "%d,%s,%f", &number1 , Name, &number2 ); 
    

    to:

    if ( sscanf( Phrase, "%d,%99[^,],%f", &number1, Name, &number2 ) != 3 )
    {
        fprintf( stderr, "Parsing error!\n" );
        exit( EXIT_FAILURE );
    }
    

    Note that you will have to additionally #include <stdlib.h> in order to be able to use exit and EXIT_FAILURE.