HaxCkzersssxz
HaxCkzersssxz

Reputation: 73

Check For Possible Int Overflow From an Input

I've been reading sources for a while but they're always talking about overflows when doing operations but how do I really check for potential int overflow the moment it was entered by the user before it can be assigned to the int identifier?

I want to check the input the moment it was entered so when found that such value already exceeded the range of value for int type data, I can put a stop to it before it even proceeds to the next part of the code.

Upvotes: 3

Views: 647

Answers (2)

bruno
bruno

Reputation: 32586

You can read a string then use strtol then check the endptr and errno, when all is ok you can assign your int var

Verbose use of strtol

#include <stdlib.h>
#include <ctype.h>
#include <errno.h>

int main()
{
  char s[32]; /* 31 characters is surely large enough for an int */

  if (scanf("%31s", s) != 1)
    puts("nok");
  else {
    errno = 0;

    char * endptr;
    long int l = strtol(s, &endptr, 10);

    if (endptr == s)
      puts("no digit");
    else if ((*endptr != 0) && !isspace(*endptr))
      puts("invalid number");
    else if (errno != 0)
      puts("overflow on long");
    else if (((int) l) != l) /* in case long and int do not have the same size */
      puts("overflow on int");
    else
      puts("you enter a valid int");
  }

  return 0;
}

Compilation and execution :

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra s.c
pi@raspberrypi:/tmp $ ./a.out
a 
no digit
pi@raspberrypi:/tmp $ ./a.out
12z
invalid number
pi@raspberrypi:/tmp $ ./a.out
123
you enter a valid int
pi@raspberrypi:/tmp $ ./a.out
12345678901
overflow on long

So to exactly answer to the question :

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>

int readInt(int * v)
{
  char s[32]; /* 31 characters is surely large enough for an int */

  if (scanf("%31s", s) != 1)
    return 0;
  else {
    errno = 0;

    char * endptr;
    long int l = strtol(s, &endptr, 10);

    if ((endptr == s) ||       /* no digit */
        ((*endptr != 0) && !isspace(*endptr)) || /* e.g. 12a */
        (errno != 0) ||        /* overflow on long */
        (((int) l) != l))      /* overflow on int */
      return 0;

    *v = (int) l;
    return 1;
  }
}


int main()
{
  int v = 123;

  if (readInt(&v))
    printf("new valid in value : %d\n", v);
  else
    printf("unvalid input, still %d\n", v);

  return 0;
}

Compilation and execution :

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra s.c
pi@raspberrypi:/tmp $ ./a.out
12
new valid in value : 12
pi@raspberrypi:/tmp $ ./a.out
9878787878787878
unvalid input, still 123
pi@raspberrypi:/tmp $ 

Upvotes: 6

Kon
Kon

Reputation: 4099

If you must read directly into an int, you can't really check for overflow before assigning.

There are ways around that if reading directly into int is not a requirement. For example, you can read into a character buffer/string and then check if the input was numeric and if it will fit into an int. If so, you then convert character buffer to an integer using standard library functions and assign to your int.

Upvotes: 1

Related Questions