Ben Warren
Ben Warren

Reputation: 5

C Program - How to deny any non-numerical input

I've just started learning the language of C, and would love your help in cleaning up / simplifying my code if you know a better way to reach the following.

I want a program to ask for a number, and if that is found then proceed to print and end, however if anything else is put in (e.g. a letter key), then I want the program to loop asking for a number until one is given.

I started off by using a simple scanf input command, but this seemed to go into an infinite loop when I tried to check if a valid number (as we define them) was put in.

So instead I have ended up with this, from playing around / looking online, but I would love to know if there is any more efficient way!

//
//  Name & Age Program
//  Created by Ben Warren on 1/3/18.
//


#include <stdio.h>
int main (void)
{

    //Setting up variables
    int num;
    char line[10]; /* this is for input */



    //Collecting input
    printf("Please enter any number? \t");
    scanf("%d", &num);


    //If Invalid input
    while (num==0)
    {
        printf("\nTry again:\t");
        fgets(line, 10, stdin); //turning input into line array
        sscanf(line, "%d",&num); //scaning for number inside line and storing it as 'num'
        if (num==0) printf("\nThat's not an number!");
    }


    //If Valid input
    {
        printf("\n%d is nice number, thank you! \n\n", num);
    *}*


    return 0;

}

Upvotes: 0

Views: 1517

Answers (4)

user3121023
user3121023

Reputation: 8286

Consider using strtol to parse a string for a long int. This also allows you to detect trailing characters. In this example if the trailing character is not a newline, the input can be rejected. strtol can also detect overflow values. Read the documentation to see how that works.

#include <stdio.h>
#include <stdlib.h>
int main (void)
{
    //Setting up variables
    long int num = 0;
    char line[40] = ""; /* this is for input */
    char *parsed = NULL;

    printf("Please enter any number? \t");
    fflush ( stdout);
    while ( fgets(line, 40, stdin))
    {
        parsed = line;//set parsed to point to start of line
        num = strtol ( line, &parsed, 10);
        if ( parsed == line) {//if parsed equals start of line there was no integer
            printf("Please enter a number? \t");
            printf("\nTry again:\t");
            fflush ( stdout);
            continue;
        }
        if ( '\n' != *parsed) {//if the last character is not a newline reject the input
            printf("Please enter only a number? \t");
            printf("\nTry again:\t");
            fflush ( stdout);
        }
        else {
            break;
        }
    }
    if ( !parsed || '\n' != *parsed) {
        fprintf ( stderr, "problem fgets\n");
        return 0;
    }
    printf("\n%ld is nice number, thank you! \n\n", num);

    return 0;
}

Upvotes: 1

Grantly
Grantly

Reputation: 2556

0 (zero) is a number...

But I see what you want to do... You can check for a valid number, using isdigit or a combination of similar functions

I think its also important to follow the advice of other answers to use the return value from scanf using code such as:

int ret = scanf("%d", &num);

and examining ret for success or failure of scanf.

Upvotes: 0

Stephen Docy
Stephen Docy

Reputation: 4788

That is not a bad approach for someone new to C. One small improvement would be to actually check the return value of scanf(), since it returns the number of arguments successfully retrieved. Then you could get away from relying on num being 0 to indicate the input was valid. Unless you do want to specifically flag 0 as invalid input.

int ret = scanf("%d", &num);

ret == 1 would mean an integer was succesffully read into num, ret == 0 would mean it was not.

Upvotes: 1

Pablo
Pablo

Reputation: 13570

Instead of checking if the value is different to 0, check the return value of sscanf. It returns the number of conversions it made. In your case it should be 1. Unless the return value is 1, keep asking for a number.

#include <stdio.h>

int main(void)
{
    int ret, num;
    char line[1024];

    do {
        printf("Enter a number: ");
        fflush(stdout);

        if(fgets(line, sizeof line, stdin) == NULL)
        {
            fprintf(stderr, "Cannot read from stdin anymore\n");
            return 1;
        }

        ret = sscanf(line, "%d", &num);

        if(ret != 1)
            fprintf(stderr, "That was not a number! Try again.\n");

    } while(ret != 1);

    printf("The number you entered is: %d\n", num);

    return 0;
}

Upvotes: 3

Related Questions