如何确定char数组表示的数字是否会溢出int?

时间:2014-02-14 03:00:36

标签: c int arrays integer-overflow

假设我有一个任意长度的char数组,它只保存数字的ASCII表示形式,用于在数组的每个条目中形成一个数字。例如

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

代表数字

  

524751089

atoi()

中使用stdlib.h.从数组中提取时

我面临的问题是当我尝试提取它时,如何检查并查看char数组所代表的数字是否会溢出unsigned int。任何关于如何在传递数据之前验证数组以获取并转换为unsigned int的建议都将非常感激。

4 个答案:

答案 0 :(得分:1)

strtoul()函数将转换为unsigned long(其范围必须至少与unsigned int一样多),并允许您检测超出范围的值。您可以进一步将结果与UINT_MAX(来自<limits.h>)进行比较,以确定它是否在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 */
}

答案 1 :(得分:0)

您可以使用std::strtol or std::strtoll并检查其返回值:

enter image description here

注意:由于这两个函数倾向于将其转换为long / long long,因此如果成功,您可能还需要检查返回值是否大于UINT_MAX

答案 2 :(得分:0)

您可以使用snprintf使用UINT_MAX填充字符缓冲区。然后有三种可能的长度案例:

  1. len(UINT_MAX)&gt; len(你的缓冲区)意味着你的缓冲区没问题。
  2. len(UINT_MAX)&lt; len(你的缓冲区)意味着你的缓冲区不会 适合。
  3. len(UINT_MAX)== len(你的缓冲区)意味着你使用strcmp比较两者。
  4. 其中len(UINT_MAX)是UINT_MAX打印的ASCII字符数。

答案 3 :(得分:0)

#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;
}