MM1
MM1

Reputation: 944

sscanf check doesn't work when given more input than required

I have an if statement that is supposed to check if the user entered exactly 4 arguments separated by a var like the following: param1,param2,param3,param4 . Problem is that it doesn't return an error if the user gives more than 4 inputs. It only returns an error when he gives less than 4.

char input[60];
char a1[42], a2[42], a3[42], a4[1];
printf("Enter info");
fgets(input, 60, stdin);
if (4 != sscanf(input,"%1[^,\n], %1[^,\n], %1[^,\n], %[^,\n]",a1, a2, a3, a4)) {
    return printf("Error"),1;
}
else
{
    printf("In");
}

I can't seem to find why. Thanks for your help

Upvotes: 3

Views: 1055

Answers (3)

hanie
hanie

Reputation: 1885

If sscanf reads data successfully it will return the number of filled variables. If you want fewer than 4 variables to be filled, to be considered successful you should say:

if (sscanf(input,"%1[^,\n], %1[^,\n], %1[^,\n], %[^,\n]",a1, a2, a3, a4)<=4) {
        printf("In");
}

Also, in failure sscanf will return EOF, but it won't return a number larger than 4.

(Note that for a4[1] you don't have space for terminator. Use at least a4[2].)

and since you want more than 4 variable filled to be considered as a failure you can add one variable to sscanf if it's filled ,it means more than 4 input was taken which is wrong and you will print error

edit: if you exactly want 4 variable, use below code:

    char input[60];
    char a1[42], a2[42], a3[42], a4[2],a5[42];
    printf("Enter info");
    fgets(input, 60, stdin);
    if (sscanf(input, "%1[^,\n], %1[^,\n], %1[^,\n], %1[^,\n], %[^,\n]", a1, a2, a3, a4,a5) == 4) {
        printf("In");
    }
    else
    {
        printf("error");
        exit(EXIT_FAILURE);
    }
}

now if you give a,b,c,d,e you will print error , because now more than 4 variables are filled.

Upvotes: 3

PatrickOfThings
PatrickOfThings

Reputation: 239

Please read this for more information about sscanf: sscanf info. The problem is this

On success, the function returns the number of variables filled. In the case of an input failure before any data could be successfully read, EOF is returned.

Your sscanf wont return more than four because the function only returns the number of variables FILLED.

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 310980

The function sscanf tries to read from the input buffer (which in this case is a string) as many items as you specified in the format string and returns the number of read items.

You should check whether the "tail" of the buffer does not contain any symbols except white spaces.

Here is a demonstrative program.

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

int main(void) 
{
    const char *input = "I , am , learning , the , programming , language , C\n";

    char a1[42], a2[42], a3[42], a4[42];

    int tail = 0;

    int result = sscanf( input, "%[^,\n] , %[^,\n] , %[^,\n] , %[^,\n]%n",
                         a1, a2, a3, a4, &tail );

    if ( result == 4 && input[strspn( input + tail, " \t\n" ) + tail] == '\0' )
    {
        printf( "%s %s %s %s\n", a1, a2, a3, a4 );
    }
    else
    {
        puts( "I am sorry but you do not yet know C." );
    }

    input = "I , am , learning , C \n";

    result = sscanf( input, "%[^,\n] , %[^,\n] , %[^,\n] , %[^,\n]%n",
                         a1, a2, a3, a4, &tail );

    if ( result == 4 && input[strspn( input + tail, " \t\n" ) + tail] == '\0' )
    {
        printf( "%s %s %s %s\n", a1, a2, a3, a4 );
    }
    else
    {
        puts( "I am sorry but you do not yet know C." );
    }

    return 0;
}

Its output is

I am sorry but you do not yet know C.
I  am  learning  C 

Upvotes: 1

Related Questions