Search code examples
cdebugginginputscanf

How to take integer input with scanf in C without using arrays?


I want to take input like the following:

Write: 1 5 3

OR

Write: 1 2

OR

Write: 2 4 9 4

OR

Write: (press Enter directly)

However, problem is that I want to take max 5 integer or less. Therefore, I wrote this expression:

scanf("%d %d %d %d %d",&a,&b,&c,&d,&e);

When I did that, if I write integers, such as 1 4 6, the program continues to want integers until I complete the number of integers to 5.

Also, sometimes, I need to skip this part by pressing enter without writing an integer. But, I can not implement that.

I did that also:

 scanf("%d%c", &firstStore,&control);
    if(control==' ')
    {
        scanf("%d%c", &secondStore,&control);
        if(control==' ')
        {
            scanf("%d%c", &thirdStore,&control);
            if(control==' ')
            {
                scanf("%d%c", &fourthStore,&control);
                if(control==' ')
                {
                    scanf("%d", &fifthStore);
                }
            }
        }
    }

The problem with this code is that I can not skip this part if I want. I mean this code wants to take minimum one integer always.

RULE:

The usage of arrays is banned.


Solution

  • Like all of the other answers, the following solution violates the rule of not using arrays, because I cannot think of any clean solution to the problem which does not use them.

    The problem with using scanf is that it will treat spaces and newline characters equally. This is not what you want.

    For line-based user input, it makes more sense to always read one line at a time, and treat every line individually. In order to read one line of user input as a string, you can use the function fgets. You can then convert this string to numbers using the function sscanf or strtol.

    Here is a solution that uses the function sscanf:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main( void )
    {
        for (;;) //infinite loop
        {
            char line[200];
            int numbers[5];
            int num_numbers;
    
            //prompt user for input
            printf( "Please enter up to 5 numbers: " );
    
            //attempt to read one line of input from user
            if ( fgets( line, sizeof line, stdin ) == NULL )
                break;
    
            //verify that line was not too long for input buffer
            if ( strchr( line, '\n' ) == NULL && !feof( stdin ) )
            {
                printf( "Line too long for input buffer!\n" );
                exit( EXIT_FAILURE );
            }
    
            //attempt to convert string to numbers
            num_numbers = sscanf(
                line,
                "%d %d %d %d %d",
                &numbers[0], &numbers[1], &numbers[2],
                &numbers[3], &numbers[4]
            );
    
            //print result
            if  ( num_numbers == 0 || num_numbers == EOF )
            {
                printf( "Was not able to match any numbers.\n" );
            }
            else
            {
                printf( "Successfully matched %d numbers:\n", num_numbers );
                for ( int i = 0; i < num_numbers; i++ )
                {
                    printf( "%d\n", numbers[i] );
                }
            }
            printf( "\n" );
        }
    }
    

    This program has the following behavior:

    Please enter up to 5 numbers: 20 30 35 40
    Successfully matched 4 numbers:
    20
    30
    35
    40
    
    Please enter up to 5 numbers: 
    Was not able to match any numbers.
    
    Please enter up to 5 numbers: 12 17
    Successfully matched 2 numbers:
    12
    17
    
    Please enter up to 5 numbers: 5
    Successfully matched 1 numbers:
    5
    

    Here is a solution which uses the function strtol instead of sscanf:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_NUMBERS 5
    
    int main( void )
    {
        for (;;) //infinite loop
        {
            char line[200], *p = line, *q;
            long numbers[MAX_NUMBERS];
            int num_numbers = 0;
    
            //prompt user for input
            printf( "Please enter up to 5 numbers: " );
    
            //attempt to read one line of input from user
            if ( fgets( line, sizeof line, stdin ) == NULL )
                break;
    
            //verify that line was not too long for input buffer
            if ( strchr( line, '\n' ) == NULL && !feof( stdin ) )
            {
                printf( "Line too long for input buffer!\n" );
                exit( EXIT_FAILURE );
            }
    
            //convert as many numbers as possible
            for ( int i = 0; i < MAX_NUMBERS; i++ )
            {
                numbers[i] = strtol( p, &q, 10 );
                if ( p == q )
                    break;
    
                p = q;
                num_numbers++;
            }
    
            //print result
            if  ( num_numbers == 0 )
            {
                printf( "Was not able to match any numbers.\n" );
            }
            else
            {
                printf( "Successfully matched %d numbers:\n", num_numbers );
                for ( int i = 0; i < num_numbers; i++ )
                {
                    printf( "%ld\n", numbers[i] );
                }
            }
            printf( "\n" );
        }
    }
    

    This second program has exactly the same output as the first program.