Domanda

Suppose that I have a char array of arbitrary length that only holds ASCII representations of numerical digits used to form a number in each entry of the array. For example

char my_array[10] = { '5', '2', '4', '7', 5, '1', '0', '8', '9', '\0' };

represents the number

524751089

when extracted from the array with atoi() from stdlib.h.

The issue I am facing is how to check and see if the number represented by the char array will overflow an unsigned int when I attempt to extract it. Any recommendations on how to validate the array before passing it to get extracted and turned into an unsigned int would be much appreciated.

È stato utile?

Soluzione

The strtoul() function will convert to an unsigned long (which must have at least as much range as unsigned int), and allows you to detect out-of-range values. You can further compare the result against UINT_MAX (from <limits.h>) to determine if it is within range of unsigned int:

unsigned long result;

errno = 0;
result = strtoul(my_array, NULL, 10);

if ((result == ULONG_MAX && errno == ERANGE) || result > UINT_MAX)
{
    /* Out of range of unsigned int */
}
else
{
    /* Within range of unsigned int */
}

Altri suggerimenti

You could use snprintf to populate a character buffer with UINT_MAX. Then there three possible cases for the length:

  1. len(UINT_MAX) > len(your buffer) means that your buffer is ok.
  2. len(UINT_MAX) < len(your buffer) means that your buffer is not going to fit.
  3. len(UINT_MAX) == len(your buffer) means that you use strcmp to compare the two.

Where len(UINT_MAX) is the number of ASCII characters UINT_MAX took to print.

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

static void check_number(const char *s)
{
        long long v;
        char *e;

        v = strtoll(s, &e, 10);
        if (errno != 0 || *e != '\0' || v < 0 || v > UINT_MAX) {
                fputs("Nope, that's not gonna fly!\n", stderr);
        }
        fputs("The number is OK!\n", stdout);
}

int main(int argc, char *argv[])
{
        const char *number;

        if (argc < 2) {
                fputs("Please specify a number in base 10 to check\n", stderr);
                return EXIT_FAILURE;
        }
        number = argv[1];
        check_number(number);
        return EXIT_SUCCESS;
}

You can use std::strtol or std::strtoll and check their return values:

enter image description here

Note: As these two functions tend to convert it to a long/long long, you may also need to check the return value is larger than UINT_MAX if successfully.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top