处理字符串转换溢出,特殊情况

时间:2014-05-05 19:30:51

标签: c string

for(end = i - 1, exp = 0, long_int = 0L; end >= start; end--, exp++)
{
    multiplier = pow(base, exp);
    sum = 0L;
    if(*(str + end) >= '0' && *(str + end) <= '9') 
        sum = (*(str + end) - '0') * multiplier;
    else if(*(str + end) >= 'A' && *(str + i) <= (base == BASE_MAX ? 'Z' : 'F')) 
        sum = (*(str + end) - 'A' + 10) * multiplier;
    else if(*(str + end) >= 'a' && *(str + i) <= (base == BASE_MAX ? 'z' : 'f'))
        sum = (*(str + end) - 'a' + 10) * multiplier;
    if(long_int >= LLONG_MAX - sum)
        break;
    else
        long_int += sum;
}
if(sign == POSITIVE && long_int > LONG_MAX)
{
    errno = ERANGE;
    return LONG_MAX;
}
else if(sign == NEGATIVE && sign * long_int < LONG_MIN)
{
    errno = ERANGE;
    return LONG_MIN;
}
else
    return (long int) sign * long_int;

我正在编写示例strtol实现。代码工作正常,但我遇到了错误的特殊情况。例如,让我们取一个字符串&#34; F0000000000000000000000000000000F&#34;如果我们尝试转换它,我们将在开始时有一些小数字,在转换的某个稍后时刻会有很大的数字。我使用的方法不会导致溢出,因为long_int(我们添加字符串的后续转换字符的最终值)是long long int和sum(这是我们将添加到long_int的值) )也是很长的int。问题是我在这两个数字的求和时会停止函数,但在本例中,long_int的值很小,我无法将总和添加到不导致溢出。 long_int不满足两个if语句的要求,因此执行转换,最终结果是在开头转换的小值。你能给我解决它的任何提示吗?

编辑: 为了给你更好的概述,我首先发布了标准gcc函数的结果,然后是我的

0xFF000000000000000000F0 in base 0 is 7FFFFFFF
strtol: Numerical result out of range
End pointer points to ""

0xFF000000000000000000F0 in base 0 is F0
strtol: Success
End pointer points to ""

EDIT2: 变量声明

#define MAX_BASE 36
..............................................................
..............................................................
long long int long_int, sum, multiplier;
int i, exp;

//base is int constant passed to a function, sign is 1 or -1 depending on a string

1 个答案:

答案 0 :(得分:0)

解决了我改变了一点。我不是从开始到结束,而是通过计算i的值作为value = value * base + char来开始累积数字,并且还更改溢出检查以检查值是否为&gt; =(LONG_MAX - char)/ base(这是积极的数字)(在我的代码中值为int_long,sum对应于char)。 - user3119781

我将其更改为仅检查&gt; (LONG_MAX - char)/ base因为它在32位机器上引起了错误。如果它等于LONG_MAX但我们停在那里我们没有溢出,所以我们不应该设置溢出为真。现在它在x86和x64架构上都能很好地工作。 - user3119781