Search code examples
cscanfformatted-input

Taking formatted input : sscanf not ignoring white spaces


I have to find out the input hours and minutes after taking inputs from the user of the form :

( Number1 : Number2 ) 

eg: ( 12 : 21 )

I should report 12 hours and 21 minutes and then again wait for input. If there is a mismatch in the given format, I should report it as invalid input. I wrote this code :

#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. if someone gives spaces between the number and :, my program considers it as invalid input, while I should treat it as valid.

Can someone explain why it is happening and any idea to get rid of this issue ? As far as I understand, sscanf should ignore all the white spaces ?


Solution

  • To allow optional spaces before ':', replace

    "%d:%d"
    

    with

    "%d :%d"
    

    sscanf() ignores white space where its format directives tell it to ignore, not everywhere. A whitespace character in the directive such as ' ' will ignore all white spaces. %d as well as other integer and floating point directives will ignore leading white space. Thus a space before %d is redundant.

    C11 7,21,6,2,8 Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier.)


    Additional considerations include using %u and unsigned as an alternate way to not accept negative numbers. strptime() is a common function used for scanning strings for time info.