手动将字符串转换为 int 并检查 C/C++ 中是不是发生溢出?
Posted
技术标签:
【中文标题】手动将字符串转换为 int 并检查 C/C++ 中是不是发生溢出?【英文标题】:Manually converting string to int and check if an overflow occured in C/C++?手动将字符串转换为 int 并检查 C/C++ 中是否发生溢出? 【发布时间】:2016-04-27 18:34:49 【问题描述】:我有以下问题 - 我编写了一个函数,它接受一个字符串并将其转换为一个 int,但我不知道如何检查是否发生任何溢出。我想在发生溢出之前返回整数的最后一个可能值。 例如:如果我有一个“2147483648”的字符串表示,我想将 214748364 作为 int 返回,因为在下一次迭代中会发生溢出。你有什么想法可以解决这个问题吗?
我的代码是:
int main ()
string s = "2147483647";
int num = 0, i = 0, buff = 0;
bool isNegative = false;
if (s[0] == '-')
isNegative = true;
i++;
while (i < s.length())
if (num < (INT_MAX/10))
num *= 10;
if (num < INT_MAX - 10)
num += s[i++] - '0';
else
break;
if (isNegative)
num = -num;
cout << "\nthe number is: " << num;
getch();
return 0;
【问题讨论】:
你能告诉我你想要的多个输入和输出吗,或者更详细地解释你想要什么。似乎有一种更简单的方法可以做到这一点。 你可以检查num
的值before乘以10。在溢出事件发生之前捕捉它。
我们可以假设不允许使用像 std::stoi
和 strtol
这样的预先存在的函数吗?
请不要涉足发布的代码。这不是一个实时的编辑反馈网站。你也需要在第一个条件下打破循环。
if (num < (INT_MAX/10)) num *= 10; if (num < INT_MAX - 10) num += s[i++] - '0';
不起作用。尝试"2147483640"
和"2147483647"
最好将您的帖子恢复为@Weather Vane 评论的原始帖子
【参考方案1】:
为了应对int
溢出,代码必须防止它。
在尝试 num*10 + digit
之前简单测试 num
和 digit
是否太大
(num >= INT_MAX/10) && ((num > INT_MAX/10) || (digit > INT_MAX%10))
用法
overflow = false;
while (i < s.length())
int digit = s[i++] - '0';
// Will num*10 + digit overflow?
if ((num >= INT_MAX/10) && ((num > INT_MAX/10) || (digit > INT_MAX%10)))
// or break per OP's coding goal
num = INT_MAX;
overflow = true;
else
num *= 10;
num += digit;
OP 的代码在INT_MIN
的文本版本上也存在问题。
Sample my_atoi()
正确返回[INT_MIN ... INT_MAX]
【讨论】:
【参考方案2】:我看到了两种可能的解决方案:
1) 在将 num 乘以 10 之前检查是否 num
2) 将字符串转换为 int 后,使用 snprintf
将 int 打印回字符串并使用 strcmp
查看字符串是否相同。
【讨论】:
认为你的意思是 `INT_MAX / 10` 这里 `INT_MAX - 10` @user4581301 两者都有,但只有num<(INT_MAX/10)
是必需的。加 9 就不能溢出INT_MAX
。
我试过if (num< (INT_MAX/10)) num *= 10; if (num < INT_MAX - 10 ) num += s[i++] - '0';
,但它不起作用。
感谢@WeatherVane。无法理解上次测试的目的。
如果这是正确答案,知道我做错了什么吗?我正在检查num<(INT_MAX/10)
然后num *= 10
【参考方案3】:
最好的办法是使用stoi
,而不是手工制作劣质的解决方案。
try
i = stoi(s);
catch(const out_of_range& /*e*/)
i = numeric_limits<int>::max();
Live Example
【讨论】:
主题中有“手动”是有原因的。我不想为此解决方案使用函数。还是谢谢。 @Calihog 我不知道你为什么这么说?您为什么要尝试重新发明标准已经提供的内容?除非……这是作业吗?以上是关于手动将字符串转换为 int 并检查 C/C++ 中是不是发生溢出?的主要内容,如果未能解决你的问题,请参考以下文章
在将字符串转换为 int 之前检查字符串是不是不是数字 [重复]
是否有更直接的方法将float转换为int而不是添加0.5f并使用截断转换?