Принимая отформатированный ввод: sscanf не игнорирует пробелы

Я должен узнать входные часы и минуты после ввода данных от пользователя формы:

( Number1 : Number2 ) 

например: ( 12: 21)

Я должен сообщить 12 часов и 21 минут, а затем снова ждать ввода. Если есть несоответствие в данном формате, я должен сообщить об этом как о неправильном вводе. Я написал этот код:

#include<stdio.h>
int main()
{
    int hourInput=0,minutesInput=0; 
    char *buffer = NULL;
    size_t size;

    do
    {
        puts("\nEnter current time : ");
        getline ( &buffer, &size, stdin );

        if ( 2 == sscanf( buffer, "%d:%d", &hourInput, &minutesInput ) && hourInput >= 0 && hourInput <= 24 && minutesInput >=0 && minutesInput <= 60  )
        {

            printf("Time is : %d Hours %d Minutes", hourInput, minutesInput );
        }

        else
        {
            puts("\nInvalid Input");
        }   
    }

    while ( buffer!=NULL && buffer[0] != '\n' );

    return 0;
}

Q. если кто-то дает пробелы между числом и :Моя программа считает это неверным вводом, в то время как я должен рассматривать его как действительный.

Может кто-нибудь объяснить, почему это происходит, и есть идея, чтобы избавиться от этой проблемы? Насколько я понимаю, sscanf должен игнорировать все пробелы?

6 ответов

Решение

Чтобы разрешить дополнительные пробелы перед ':', замените

"%d:%d"

с

"%d :%d"

sscanf() игнорирует пробел, где его директивы формата говорят ему игнорировать, а не везде. Пробельный символ в директиве, такой как ' ' будет игнорировать все пробелы. %d а также другие целочисленные и с плавающей точкой директивы будут игнорировать начальные пробелы. Таким образом, пространство перед %d избыточно

C11 7,21,6,2,8 Входные пробельные символы (как указано в функции isspace) пропускаются, если в спецификации не указан спецификатор [, c или n.)


Дополнительные соображения включают использование %u а также unsigned как альтернативный способ не принимать отрицательные числа. strptime() это общая функция, используемая для сканирования строк на предмет временной информации.

На скэнф ман пейдж

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ SSCANF -

Эти функции возвращают количество назначенных элементов ввода. Это может быть меньше, чем предусмотрено, или даже равно нулю, в случае сбоя сопоставления. Ноль указывает, что, хотя вход был доступен, преобразований не было назначено; обычно это происходит из-за недопустимого входного символа, такого как буквенный символ для преобразования `%d'. Значение E OF возвращается, если произошел сбой ввода до того, как произойдет какое-либо преобразование, например конец файла. Если после начала преобразования возникает ошибка или конец файла, возвращается количество успешно завершенных преобразований.

Сейчас,

если кто-то дает пробелы между числом и:, моя программа считает это неверным вводом

Да, он должен считать это неправильным, потому что sscanf читает из buffer точно так же, как %d:%d, но если символ во входном потоке конфликтует с форматной строкой, функция завершается, заканчиваясь ошибкой сопоставления.

Ожидается, что символы вне спецификаций преобразования будут соответствовать последовательности символов во входном потоке; соответствующие символы во входном потоке сканируются, но не сохраняются. (Пожалуйста, обратите внимание на выделенное предложение жирным шрифтом)

т.е. sscanf во время записи в память игнорирует пробелы.

1-я вещь выделяет память перед использованием buffer

2-й это C++ программа или C как getline это не C standard функция.

Проверь это

int main()
{
        int x=0,y=0;
        char bff[]="7        8";
        sscanf(bff,"%d%d",&x,&y);
        printf("%d %d",x,y);
}

о / п-7 8

Я думаю, что если вы поставите пробел до и после двоеточия, он будет игнорировать все пробелы и все равно будет работать, если они не ставят пробелы до и после двоеточия. Как это:

sscanf( buffer, "%d : %d", &hourInput, &minutesInput )

Избегайте сравнения sscanf() возвращаемое значение В вашем случае это всегда зависит от ввода пользователя. Если пользователь вводит пробелы между входными данными, это значение изменяется.

Используйте "%d: %d" в качестве строки формата. это будет работать с и без пробелов.

Другие вопросы по тегам