Pregunta

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.

¿Fue útil?

Solución

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 */
}

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top