3

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

MM1
  • 912
  • 1
  • 10
  • 28
  • The system hopes that you will call sscanf one more.:) – Vlad from Moscow Apr 06 '20 at 18:41
  • `sscanf` does not ensure that the whole line is read and if you provide only four conversion formats, the maximum value `scanf` will return is 5. If you want to detect extra characters, you could scan a dummy char. – M Oehm Apr 06 '20 at 18:43
  • (But why is `a4` only 1 char long? That array can't hold any sensible string. And the `%1[...]` with the `1` before the bracket will try to scan at most 1 character.) – M Oehm Apr 06 '20 at 18:44

3 Answers3

3

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.

hanie
  • 1,863
  • 3
  • 9
  • 19
  • Wait, I think I haven't been clear, I want that only 4 variables to be filled is considered good, which means if the user enter less or more than 4 variables he'll get an error – MM1 Apr 06 '20 at 22:24
  • But there's still the problem that if the user enters a,b,c for example he'll not get an error, I want exactly 4 inputs like a,b,c,d, thanks for your help! – MM1 Apr 07 '20 at 14:24
  • No sorry I meant exactly 4 inputs – MM1 Apr 07 '20 at 14:27
1

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.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
PatrickOfThings
  • 237
  • 1
  • 9
1

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 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335