Search code examples
cintscanfoverflow

C - Control the Overflow (Insertion of values ​from the keyboard)


I am trying to limit the user adding minimum and maximum values to it:

int verificate( int num, int min,  int max) {
while( (num > max) || (num < min) ) {
    printf("\tBig number try again:");
    scanf(" %d",&num);
}
return num;
}

Main.c

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define MIN 0
#define MAX INT_MAX

void main() {
int num1;
scanf(" %d",&num1);
num1=verificate(num1,MIN,MAX);
printf("Number = %d",num1);
}

The problem I have is if the user inserts a bigger number (num1>2147483647) automatically the result is 1410065407, and also if the user inserts the biggest negative value (num1=-999999999999) automatically the result is -1215752191. There's any way that I can control this? And make the user to insert again the value?


Solution

  • scanf() behavior on integer conversion overflow is undefined.

    Use fgets() to read all input. Ditch scanf().

    Use strtol() to parse the string: better error handling and overflow detection.

    #include <errno.h>
    #include <stdio.h>
    
    // return true when good
    // return false on EOF    
    bool verificate(int *dest, int min, int max) {
      char buf[80];
      while (fgets(buf, sizeof buf, stdin)) {
        char *endptr;
        errno = 0;
        long num = strtol(buf, &endptr, 0);
        //  numeric input?     overflow?           >= min?       <= max? 
        if (endptr > buf && errno != ERANGE && num >= min && num <= max) {
          *dest = (int) num;
          return true;
        }
        printf("\tNon-numeric input or out of %d %d range:\n", min, max);
      }
      return false;
    }
    

    Sample usage

    #define MIN 0
    #define MAX INT_MAX
    
    int main() {
      int num1 = 0;
      if (verificate(&num1, MIN, MAX) {
        printf("Number = %d",num1);
      } 
    }