проверка sscanf не работает, когда вводится больше данных, чем требуется - PullRequest
3 голосов
/ 06 апреля 2020

У меня есть оператор if, который должен проверять, вводил ли пользователь точно 4 аргумента, разделенных переменной var, как показано ниже: param1, param2, param3, param4. Проблема в том, что он не возвращает ошибку, если пользователь дает более 4 входных данных. Он возвращает ошибку только тогда, когда он дает меньше 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");
}

Я не могу понять, почему. Спасибо за вашу помощь

Ответы [ 3 ]

3 голосов
/ 06 апреля 2020

Если sscanf считывает данные успешно, возвращается количество заполненных переменных. Если вы хотите, чтобы меньше чем 4 переменных было заполнено, чтобы считаться успешным, вы должны сказать:

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

Кроме того, при ошибке sscanf вернет EOF, но не вернет число больше 4.

(обратите внимание, что для a4[1] у вас нет места для терминатора. Используйте по крайней мере a4[2].)

и, поскольку вы хотите больше 4 заполненная переменная, которая будет рассматриваться как ошибка, вы можете добавить одну переменную к sscanf, если она заполнена, это означает, что было взято более 4 входных данных, что неверно, и вы напечатаете ошибку

edit : если вам нужна переменная 4, используйте следующий код:

    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);
    }
}

сейчас, если вы введете a,b,c,d,e, вы напечатаете ошибку, потому что теперь заполнено более 4 переменных.

1 голос
/ 06 апреля 2020

Функция sscanf пытается прочитать из входного буфера (который в данном случае является строкой) столько элементов, сколько вы указали в строке формата, и возвращает количество прочитанных элементов.

Вам следует проверьте, не содержит ли «хвост» буфера никаких символов, кроме пробелов.

Вот демонстрационная программа.

#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;
}

Его вывод

I am sorry but you do not yet know C.
I  am  learning  C 
1 голос
/ 06 апреля 2020

Пожалуйста, прочтите это для получения дополнительной информации о sscanf: sscanf info . Проблема заключается в следующем:

В случае успеха функция возвращает количество заполненных переменных. В случае сбоя ввода до того, как какие-либо данные могут быть успешно прочитаны, возвращается EOF.

Ваш sscanf не вернет больше четырех, потому что функция возвращает только количество переменных FILLED.

...