我有一个问题,在输出,虽然我定义了宏的最大长长处理溢出,但它仍然给我一个错误的输出
# define LLONG_MAX 9223372036854775807LL
正如你在这里看到的,
#include "libft.h"
static int iswhitespace(char c)
{
if (c == ' ' || c == '\t' || c == '\n'
|| c == '\r' || c == '\v' || c == '\f')
return (1);
return (0);
}
仅用于白色空格的函数
static int ft_result(int count, long long int n, int sign)
{
if (count > 1)
return (0);
else if (n > LLONG_MAX && sign == -1)
return (0);
else if (n > LLONG_MAX && sign == 1)
return (-1);
else
return (n * sign);
}
我认为问题在于这个计算结果的函数
int ft_atoi(const char *str)
{
int i;
unsigned long long n;
int sign;
int count;
i = 0;
n = 0;
sign = 1;
count = 0;
if (str == NULL || (str != NULL && *str == '\0'))
return (0);
while (iswhitespace(str[i]))
i++;
while (str[i] == '-' || str[i] == '+')
{
if (str[i] == '-')
sign *= -1;
count++;
i++;
}
while (str[i] >= '0' && str[i] <= '9')
n = (n * 10) + (str[i++] - '0');
return (ft_result(count, n, sign));
}
对于主函数,我认为逻辑是可靠的,如果有潜在的segfault,请指出
#include <stdio.h>
int main()
{
printf("my atoi: %d || original : %d",ft_atoi("9999999999999999999999999"),atoi("9999999999999999999999999"));
}
正如你所看到的,这只是函数输出之间的比较:
我的atoi
:1241513983||原始:-1
2条答案
按热度按时间ujv3wf0j1#
if (n > LLONG_MAX && sign == 1)
比if (n > INT_MAX && sign == 1)
更有意义,但代码仍然存在以下问题:考虑到
int
和long long/unsigned long long
可能是相同的宽度,因此使用(unsigned) long long
并不能帮助解决int ft_atoi(const char *str)
问题,因为它不能提供int
的额外范围。学究式地:
INT_MAX == ULLONG_MAX
可以是相同的。在任何情况下,都不需要更宽的类型。
未阻止溢出
while (str[i] >= '0' && str[i] <= '9') n = (n * 10) + (str[i++] - '0');
存在溢出和 * 未定义行为 *(UB)的风险。相反,测试
(n * 10) + (str[i++] - '0')
是否可能溢出。LLONG_MIN/INT_MIN
的正幅值累加失败n * sign
不能很好地返回INT_MIN
,因为没有n
,所以n * -1
导致INT_MIN
是一种可移植的定义良好的方式。不使用较宽类型的备选项:
已测试的代码不使用比
int
更宽的类型。qyswt5oh2#
好的,我想我把它修好了,谢谢你的帮助,如果有人想知道这是解决办法的话。
libft. h包含:#include<limits.h>我没有定义自己的宏
我做了测试用例里面的计算,并使用指针跳过空格和符号
输出:我的回答:-1||原始:-1
如果有人想知道为什么我不使用库,我不允许使用一个函数,我没有重新创建printf只是为了测试我身边