Taking formatted input : sscanf not ignoring white spaces

3.5k Views Asked by At

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 ?

6

There are 6 best solutions below

0
On BEST ANSWER

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.

1
On

Avoid comparing sscanf() return value. In your case, it is always depends on the user input. If user gives spaces between input this value changes.

0
On

I think if you put a space before and after the colon, it will ignore any whitespace and still work when they don't put spaces before and after the colon. Like this:

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

use "%d : %d" as format string. it will work with and without spaces.

1
On

1st thing allocate memory before using buffer

2nd is this a C++ program or C as getline is not a C standard function.

Check this

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

o/p-7 8

0
On

On sscanf man pagez

RETURN VALUE OF SSCANF -

These functions return the number of input items assigned. This can be fewer than provided for, or even zero, in the event of a matching fail- ure. Zero indicates that, although there was input available, no conver- sions were assigned; typically this is due to an invalid input character, such as an alphabetic character for a `%d' conversion. The value EOF is returned if an input failure occurs before any conversion such as an end- of-file occurs. If an error or end-of-file occurs after conversion has begun, the number of conversions which were successfully completed is returned.

Now,

if someone gives spaces between the number and :, my program considers it as invalid input

Yes , it should consider it wrong because the sscanf reads the from the buffer in exactly the same way as %d:%d,but if a character in the input stream conflicts with format-string, the function ends, ending with a matching failure.

Characters outside of conversion specifications are expected to match the sequence of characters in the input stream; the matched characters in the input stream are scanned but not stored. (Please see the emphasis on the sentence in bold)

i.e, sscanf while writing to the memory ignores whitespaces.