performing range checks on variable values

This is a discussion on performing range checks on variable values within the C Programming forums, part of the General Programming Boards category; I mean checking if the value of variable is within the permissible range other wise simply report error message and ...

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    87

    performing range checks on variable values

    I mean checking if the value of variable is within the permissible range other wise simply report error message and quit. For eg. int is always between INT_MIN and INT_MAX. Is there any elegant way to do this ?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,462
    Just compare the value with the endpoints of the range. Of course, an int will be between INT_MIN and INT_MAX anyway.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,212
    If the intent of the question is checking if input data fits in an int, then ....

    strtol() [for conversion of a string to a long] returns zero if the conversion is not possible. If the data in the string cannot be represented in a long (eg value too big) the function returns LONG_MIN or LONG_MAX (depending on sign) and sets errno to the value of ERANGE.

    You might also wish to look up functions like atoi() which, except for behaviour on error, are equivalent to strtol() but simpler to use.

    Similar functions exist for converting a string to other types.

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Quote Originally Posted by grumpy View Post
    If the intent of the question is checking if input data fits in an int, then ....

    strtol() [for conversion of a string to a long] returns zero if the conversion is not possible. If the data in the string cannot be represented in a long (eg value too big) the function returns LONG_MIN or LONG_MAX (depending on sign) and sets errno to the value of ERANGE.

    You might also wish to look up functions like atoi() which, except for behaviour on error, are equivalent to strtol() but simpler to use.

    Similar functions exist for converting a string to other types.
    what about underflow, overflow and divide by zero errors which often happen ? Should I write a library of my own or is there some C implementation out there that I can use.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by broli86 View Post
    what about underflow, overflow and divide by zero errors which often happen ? Should I write a library of my own or is there some C implementation out there that I can use.
    Check for that possibility before you do the operation.
    Ex. make sure the denominator is != 0

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,212
    Quote Originally Posted by broli86 View Post
    what about underflow, overflow and divide by zero errors which often happen ?
    Those things do not happen with functions like strtol() -- these functions catch the overflow by parsing the input string, and then return a values and/or assign error status if required.

    It would be a fairly oddball parsing technique that could produce a divide by zero error when attempting to interpret contents of a string as an integral value.

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Quote Originally Posted by grumpy View Post
    Those things do not happen with functions like strtol() -- these functions catch the overflow by parsing the input string, and then return a values and/or assign error status if required.

    Oh that's great. In that I case I will be safer with strtol than using scanf and scanf looks very ugly for some reason.

    Quote Originally Posted by grumpy View Post
    It would be a fairly oddball parsing technique that could produce a divide by zero error when attempting to interpret contents of a string as an integral value.
    So you are saying that using strtol can cause divide by zero error ?

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,462
    So you are saying that using strtol can cause divide by zero error ?
    No, grumpy stated that "those things do not happen with functions like strtol()", which is true.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Quote Originally Posted by laserlight View Post
    No, grumpy stated that "those things do not happen with functions like strtol()", which is true.
    Ok . What about when reading double precision data from a file ? Is it safer to use fgets or fscanf ? The file format is as follows:

    3.456789 0.000000 -1.234567
    4.567889 0.000001 -10.22222
    ..................................................
    ..................................................

    If I use fgets, I presume I will be reading 3 strings and then converting each to double precision using strtol ? But I think fgets only allows one string at a time.

  10. #10
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    602
    You may want to read up on strtol

    performing range checks on variable values

    The intended purpose is for conversion. I would not base my calculations for boundary checking on this.

    I would recommend to use assert() if at all possible if you want to check for a condition and exit. If you are debugging.


    http://www.cprogramming.com/tips/sho...ount=30&page=0

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Hello, I looked up the strto* family of functions and I applied it my problem of scanning a size_t variable. Here's my program and something seems to be going wrong :
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <math.h>
    #include <limits.h>
    
    int main(void)
    {
       size_t a; /* size_t variable */
       char a_str[50]; /* String to be converted */
       char *ptr = NULL;
       char *endptr;
       unsigned long l;
    
       if (fgets(a_str, 50, stdin) == NULL)
       {
         fprintf(stderr, "Error while entering the stirng\n");
         return (1);
       }
    
       if ((ptr = strchr(a_str, '\n')) != NULL)
       {
         *ptr = '\0';
       }
    
       errno = 0;
    
       l =  strtoul(a_str, &endptr, 0); /* Convert string to long unsigned first */
    
       if (errno == ERANGE)
       {
         if (abs(l) == HUGE_VAL)
         {
           fprintf(stderr, "OVERFLOW\n");
           return (1);
         }
         else
           if (l == 0)
           {
             fprintf(stderr, "UNDERFLOW\n");
             return (1);
           }
       }
       else
       {
         if (l == 0.0)
         {
           fprintf(stderr, "Conversion failed\n");
           return (1);
         }
       }
    
       if (l <= UINT_MAX) /* size_t typedefed as uint on my tcc */
       {
         a = (size_t)l;
         printf("\n%lu", (unsigned long)a);
       }
       else
       {
         printf("OVERFLOW");
       }
       return (0);
    
    }
    The program gives proper output until you enter a negative number for
    which, ideally, it should print "UNDERFLOW" but it seems to print
    "Conversion failed".

  12. #12
    Registered User
    Join Date
    Apr 2008
    Posts
    87
    Quote Originally Posted by slingerland3g View Post
    You may want to read up on strtol


    performing range checks on variable values

    The intended purpose is for conversion. I would not base my calculations for boundary checking on this.

    I would recommend to use assert() if at all possible if you want to check for a condition and exit. If you are debugging.


    http://www.cprogramming.com/tips/sho...ount=30&page=0
    Well I would have used assert, but I don't really want to exit on all situations. Only some fatal error situations like memory allocation failure.

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    The program gives proper output until you enter a negative number for
    which, ideally, it should print "UNDERFLOW" but it seems to print
    "Conversion failed".
    strtoul() doesn't even try to convert numbers that begin with "-". It sees that they'll always fail. So it just returns immediately, I guess, without setting errno.

    If you want to tell if it was a negative number, you could use something like this . . . .
    Code:
    int is_negative(const char *string) {
        while(isspace(*string)) string ++;
        return *string == '-';
    }
    [edit] By the way:
    Code:
    if (fgets(a_str, 50, stdin) == NULL)
    This is a bit easier to maintain:
    Code:
    if (fgets(a_str, sizeof(a_str), stdin) == NULL)
    [/edit]
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. range of values in an if statement
    By cosmiccomputing in forum C Programming
    Replies: 3
    Last Post: 06-01-2008, 10:20 PM
  2. Range of Values
    By devilsknight in forum C Programming
    Replies: 1
    Last Post: 06-03-2006, 03:16 PM
  3. Replies: 5
    Last Post: 08-09-2004, 08:25 PM
  4. unsigned char vs signed char and range of values
    By Silvercord in forum C++ Programming
    Replies: 5
    Last Post: 01-22-2003, 12:30 PM
  5. Can yoou return a range of values stored into a integer?
    By correlcj in forum C++ Programming
    Replies: 5
    Last Post: 10-28-2002, 03:24 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21