如何在C / C ++中检查整数溢出?

我想知道如何确定C / C ++中的溢出。 如果我的整数输入是9999999999999999999999,这是一个非常大的数字,如果我运行下面的代码,我将得到一个垃圾输出。

#include  int main(){ int a; scanf("%d",&a); printf("%d",a); return 0; } 

有没有办法知道,如果输入是一个大数字,我可以输出“输入太大”。

注意,我已经检查了如何检测整数溢出? 。 但问题与我的问题不同。

在您的情况下,读取字符串中的输入,然后根据长度做出决定。 你可以在字符串中编码整数,长整数等的限制,如果输入的长度(数字的数量)等于或小于你的一个字符串限制,移动一个与比较,如果它小于字符串表示限制,您可以安全地将其转换为整数类型。

UPDATE

或者如果您愿意,可以在C ++中使用流操作符,正如David Brown建议的那样……

正如在注释中发布的那样,有一种方法可以在算术运算后检测溢出,这在这种情况下部分有用:

你可以做的是通过char读取char并检查每一步的溢出:(不确定你是否使用C或C ++,包括

 int x=0; while(1){ char c='\0'; scanf(" %c",&c); if (c<'0' || c>'9') break;//Input finished if (!willOverflow(x,c-'0')) x=x*10+c-'0'; else break;//Overflow would happen, handle code belongs here } int willOverflow(int cur,int next){//Perform your overflow check //for example i would use return ((INT_MAX-next)/10) 

这会捕获其他错误以及溢出:

 #include  #include  #include  int main() { std::string line; std::getline(std::cin, line); try { std::cout << boost::lexical_cast(line) << "\n"; } catch (const boost::bad_lexical_cast &e) { std::cout << e.what() << "\n"; } } 

Boost当然是非标准的,你必须为你的系统安装它。 如果失败了,或者你想让库函数区分输入“99999999999”和“123abc”,那么你将不得不使用std::stoistd::strtol 。 两者都不太方便。

是的,您可以检查从输入读取的数字溢出,但scanf不是这样做的方法。 当输入数字太大而无法表示为intscanf("%d", &n)调用scanf("%d", &n)实际上具有未定义的行为 。 (恕我直言,这是非常不幸的,并且使scanf几乎不可能安全地用于数字输入。)

但是strto*function:

  • strtollong
  • strtolllong long
  • strtoulunsigned long
  • strtoull (对于unsigned long long
  • strtoull (对于unsigned long long
  • strtoffloat
  • strtoddouble
  • strtoldlong double

虽然它们使用起来有点困难,但对所有输入都有明确定义的行为。

使用fgets读取一行输入,然后使用strto*函数之一将输入转换为适当类型的数字。

溢出时,这些函数返回相应类型的最小值或最大值,并将errnoERANGE 。 您应该在通话前将errno0 。 (检查errno设置可以区分溢出和2147483647的实际输入。)

阅读man文档,了解相关function的详细信息。

由于int没有strtoi函数,你可以使用strtol ,检查输入是否为有效long ,然后检查long值是否在INT_MIN范围内INT_MAX ; 类似于unsigned intstrtoul

如果你需要检查这样的事情,读一个字符串,然后检查字符串是要走的路。