【问题标题】:C sscanf() force number inputC sscanf() 强制数字输入
【发布时间】:2017-01-28 23:58:25
【问题描述】:

我正在尝试使用 sscanf() 来验证命令行输入

我只想要像 1、0.1、0.111 这样的东西通过, 不是 a12 12a 或 1.2a

我试过了

if (sscanf(input, "%f", &val) != 1) { // to check for 1 successful conversion
      printf("invalid input");
}

但我似乎也让无效输入通过。

有什么建议吗?

【问题讨论】:

  • 不要给scanf()打两次电话。 if() 不是测试第一个是否成功,而是在它之后进行第二次扫描。
  • 这实际上不是我的代码的样子。我只是想帮助读者理解。我只有第二行
  • 显然它并没有帮助我理解。发布您的实际代码、您期望的结果以及您得到的结果。
  • scanf 不是严格的解析器。它只是一个快速而肮脏的解析器,对一次性代码很有用。如果您想要严格解析,请查看strtokstrtolstrtod
  • 我建议接受输入,不管它是什么,作为一个字符串,然后测试它。

标签: c scanf stdio


【解决方案1】:

sscanf(input, "%f", &var) 遇到输入12a1.2a 时,它会停在无效的输入部分,剩下的字符可供后续格式代码读取。

考虑以下字符串在有效数字后面的浮点数中包含无效字符:

  • 1.0 2.0(一个空格)
  • 1.0, 2.0(逗号)
  • 1.0a 2.0(一封信)

空格和逗号对我们的人类解析引擎来说看起来不错;当发现无效字符时,机器浮点解析就会停止,无论它是人类可接受的空格或逗号,还是丑陋的字母。

如果你想确保浮点数后面不会紧跟垃圾,你可以使用类似的东西:

n = sscanf(input, "%f%c", &var, &ch);
if (n == 1 ||
     (n == 2 && (ch == ' ' || ch == ',' || ...))) {
    // ...
}

【讨论】:

  • 为什么投反对票?投反对票很好,但请给出理由。
  • 我投了赞成票,不确定谁投了反对票。如果我想在浮动之前考虑垃圾怎么办?
  • float 之前的垃圾会阻止%f 转换成功,sscanf 将返回 0。
【解决方案2】:

sscanf 不是你的朋友,在这里。即使您检查结果 确保您成功阅读了一个完整的论点,这不会 真正保证输入在有意义的意义上是有效的。

给定输入:

1!!!1!oneone!

%f 解析将在读取第一个 1 后停止(但成功), 并将读取指针留在以下!。这可能不是什么 您认为“有效输入”。

如果同一行中的任何内容都被视为垃圾,那么它会得到 困难,因为scanf 不区分空格和 换行符。也许尝试这样的事情:

int main(int argc, char *argv[])
{

    float val;
    char c;
    if (sscanf(argv[1],"%f%c",&val,&c)!=1)
    {
        printf("invalid input");
    }
    return 0;
}

现在它将验证所有命令行输入是否为浮点数输入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-13
    • 2014-05-07
    • 1970-01-01
    • 2016-12-22
    • 2017-08-22
    • 2018-05-15
    相关资源
    最近更新 更多