【问题标题】:Scanf() not able to detect wrong inputScanf() 无法检测到错误输入
【发布时间】:2022-06-30 00:02:37
【问题描述】:
int i,f;
f = scanf("%d",&i);

当我输入输入为 3333333333333333333333(大于 int 的容量)时。 f的值不应该是0吗?

【问题讨论】:

  • scanf() 和朋友不要做溢出检查。
  • 忘记使用scanf 进行用户输入然后验证该输入的想法,这是无法完成的,scanf 的设计并未考虑到这一点。使用fgets 读取整行,然后解析输入,可能使用strtolstrtod
  • 继 Jabberwocky 的评论。 scanf 非常适合快速而肮脏的输入。但是,面对您希望干净可靠地检测到的可能错误,对于强大的真实世界输入来说,这绝对是糟糕的——基本上是无用的。
  • scanf 函数——整个家族——在数字输入溢出时具有未定义的行为。这意味着:不仅无法检测到这种输入错误,C 库还允许使您的程序崩溃,因为输入的数字太多。而且我不能认为编译器可以从这种情况中得出一个虚假的假设,但我不能排除这种可能性。 scanf 系列已按规定损坏,根本不应使用。

标签: c unix error-handling integer scanf


【解决方案1】:

不,这样无法检测到。您需要先设置errno = 0;,然后检查它是否有范围错误:

#include <errno.h>

// ...

    errno = 0;
    f = scanf("%d",&i);
    if(f == 1 && errno != ERANGE) {
        // success
    }

这是否是一个可移植的解决方案值得商榷,但它适用于 的最新版本。

Demo

检测这种情况的更好(如 便携式)选项是使用strtol()

【讨论】:

  • 我不同意这是个好建议。在做某事之前将errno 设置为0,然后再对其进行测试,这几乎是不可靠的。对于极少数库函数,它被记录为工作,但我不相信scanf 是其中之一。
  • 我认为 ERANGE 是 GNU libc 的东西,不是标准的。此外,手册页似乎不清楚scanf 在出现范围错误时返回的内容。所以这个答案可以使用更多的解释/参考。
  • @TedLyngmo 我刚刚在我的机器上尝试过,但没有成功。而且,我很抱歉,“我能想到的唯一方法”听起来不是一个很好的理由来回答这个问题。
  • @TedLyngmo 您提到的scanf 文档提到了strtol 和亲戚,但它并没有说这些函数实际上 使用过,也没有在任何地方提到errno .
  • @TedLyngmo 谢谢!我特此删除我没有给你的反对票! :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-12
  • 2022-09-29
  • 1970-01-01
  • 2019-02-23
  • 2021-12-25
  • 2014-04-16
  • 1970-01-01
相关资源
最近更新 更多