Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C programming - Loop until user inputs number scanf

I need help with error checking for my program. I'm asking the user to input a integer and I would like to check if the users input is a integer. If not, repeat the scanf.

My code:

int main(void){

  int number1, number2;
  int sum;

  //asks user for integers to add
  printf("Please enter the first integer to add.");
  scanf("%d",&number1);

  printf("Please enter the second integer to add.");
  scanf("%d",&number2);
  //adds integers
  sum = number1 + number2;

  //prints sum
  printf("Sum of %d and %d = %d \n",number1, number2, sum);

  //checks if sum is divisable by 3
  if(sum%3 == 0){
    printf("The sum of these two integers is a multiple of 3!\n");
  }else {
    printf("The sum of these two integers is not a multiple of 3...\n");
  }
  return 0;
}
like image 232
Asia x3 Avatar asked Sep 10 '14 12:09

Asia x3


People also ask

Can you put scanf in a while loop?

scanf() function returns number of items it successfully reads. Since in your case it is reading one number n , scanf() returns 1. When you give a input file for the code to run, it returns 0 on reaching end of the file (EOF).

How do I scanf a number?

scanf("%d", &b); The program will read in an integer value that the user enters on the keyboard (%d is for integers, as is printf, so b must be declared as an int) and place that value into b. The scanf function uses the same placeholders as printf: int uses %d.

What is %d scanf?

The “%d” in scanf allows the function to recognise user input as being of an integer data type, which matches the data type of our variable number. The ampersand (&) allows us to pass the address of variable number which is the place in memory where we store the information that scanf read.

How does scanf %s work in C?

In scanf() you usually pass an array to match a %s specifier, then a pointer to the first element of the array is used in it's place. For other specifiers like %d you need to pass the address of the target variable to allow scanf() to store the result in it.


2 Answers

scanf returns the count of items that it has successfully read according to your format. You can set up a loop that exits only when scanf("%d", &number2); returns 1. The trick, however, is to ignore invalid data when scanf returns zero, so the code would look like this:

while (scanf("%d",&number2) != 1) {
    // Tell the user that the entry was invalid
    printf("You did not enter a valid number\n");
    // Asterisk * tells scanf to read and ignore the value
    scanf("%*s");
}

Since you read a number more than once in your code, consider making a function to hide this loop, and call this function twice in your main to avoid duplication.

like image 156
Sergey Kalinichenko Avatar answered Sep 28 '22 07:09

Sergey Kalinichenko


Here is a solution of your problem. I just modified some of your code. Read comments for any explanations.

#include<stdio.h>

#include<stdlib.h>      //included to use atoi()
#include<ctype.h>       //included to use isalpha()

#define LEN 3   //for two digit numbers

int main(void)
{

    char *num1=malloc(LEN);
    char *num2=malloc(LEN);
    int i,flag=0;

    int number1,number2;
    int sum;

    do
    {
        printf("Please enter the first integer to add = ");
        scanf("%s",num1);
        for (i=0; i<LEN; i++)   //check for every letter of num1
        {
            if (isalpha(num1[i]))   //isalpha(num1[i]) returns true if num1[i] is alphabet
            {                       //isalpha() is defined in ctype.h
                flag=1;             //set flag to 1 if num1[i] is a alphabet
            }
        }
        if(flag)
        {
            printf("Not a valid Integer\n");
            flag=0;
            continue;
        }
        else
        {
            break;
        }
    } while(1);

    do
    {
        printf("Please enter the second integer to add = ");
        scanf("%s",num2);
        for (i=0; i<LEN; i++)
        {
            if (isalpha(num2[i]))
            {
                flag=1;
            }
        }
        if(flag)
        {
            printf("Not a valid Integer\n");
            flag=0;
            continue;
        }
        else
        {
            break;
        }
    } while(1);

    //strings to integers
    number1= atoi(num1);    //atoi() is defined in stdlib.h
    number2= atoi(num2);

    //adds integers
    sum = number1 + number2;

    //prints sum
    printf("Sum of %d and %d = %d \n",number1, number2, sum);

    //checks if sum is divisable by 3
    if(sum%3 == 0)
    {
        printf("The sum of these two integers is a multiple of 3!\n");
    }
    else
    {
        printf("The sum of these two integers is not a multiple of 3...\n");
    }
    return 0;
}

I designed this for only two digit numbers, but it is working fine for more than two digit numbers for me. Please let me know that same is happening in your case.
And if you will find why this is happening please comment.

And you can also use strtol() instead of atoi(). I am not using it because of small values.

Difference between atoi() and strtol()

atoi()
Pro: Simple.
Pro: Convert to an int.
Pro: In the C standard library.
Pro: Fast.
Con: No error handling.
Con: Handle neither hexadecimal nor octal.

strtol()
Pro: Simple.
Pro: In the C standard library.
Pro: Good error handling.
Pro: Fast.
Con: Convert to a long, not int which may differ in size.

like image 30
Sachin Avatar answered Sep 28 '22 07:09

Sachin