0

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;

}
2
  • There's a specialized Stackexchange-Site called codereview where this question would fit better. Commented Mar 2, 2018 at 0:19
  • There are number of questions about 'how to ensure that only an integer' (or floating point number) is entered. A simple 'scanf()` format is not usually one of the answers. Commented Mar 2, 2018 at 4:36

4 Answers 4

3

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;
}
Sign up to request clarification or add additional context in comments.

Comments

1

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.

1 Comment

"if anything else is put in ..., then I want the program to loop" and scanf("%d", &num) does not consume the non-numeric input makes for an incomplete solution. OP's use of fgets(); sscanf(); needs work, but is closer to a working solution than scanf().
1

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;
}

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.