【问题标题】:Why passing string to scanf() compiles fine in C?为什么将字符串传递给 scanf() 在 C 中编译得很好?
【发布时间】:2015-06-10 16:29:58
【问题描述】:

我最近编写了一个简单的程序,我错误地使用 scanf() 而不是 printf() 在控制台上显示消息。我原以为会出现编译时错误,但它编译得很好,在运行时没有警告和崩溃。我知道 scanf() 用于从键盘获取输入。我不应该在以下程序中收到错误吗?

#include <stdio.h>
int main()
{
    scanf("Hello world");   // oops, It had to be printf()
    return 0;
}

它是否调用未定义的行为(UB)? C标准中有没有提到这一点?为什么在编译时不检查是否将正确和有效的参数传递给 scanf() 函数?

【问题讨论】:

  • 无法重现崩溃。该程序对我来说运行良好。
  • 代码对我来说看起来是正确的,并且在编译和运行时应该可以正常完成。你怎么知道它“崩溃”?碰撞症状是什么?
  • 我很确定语法暗示:没有编译失败和没有崩溃

标签: c scanf undefined-behavior


【解决方案1】:

代码运行正常。确实,scanf 被声明了

int scanf(const char *format, ...);

幸运的是,您的format 不包含任何%,在... 中没有对应关系,这会调用UB。
此外,format 是一个字符串文字,它允许编译器通过它确保您传递了关于格式说明符的正确类型的参数,作为启用更高警告级别的健全性检查的一部分。 (-Wformat 系列)

【讨论】:

    【解决方案2】:

    将字符串传递给scanf 可以正常编译,因为scanf 期望将字符串作为它的第一个参数。有关详细的scanf 说明,请参阅文档或编程手册。

    【讨论】:

      【解决方案3】:

      编译器无法读懂你的想法。

      printf("Hello world")scanf("Hello world") 的格式都很好。

      【讨论】:

        【解决方案4】:

        scanf does take a string paramater。这就是它编译良好的原因,但您的参数似乎与预期的不匹配,因此它在运行时崩溃(或只是退出)。

        【讨论】:

        • 我真的怀疑它会崩溃......为什么会这样? scanf 只是从输入中读取字符并将它们与格式字符串进行比较。当比较失败时,scanf 会返回一些错误,但不会“崩溃”。
        猜你喜欢
        • 2015-04-10
        • 2020-11-23
        • 2020-04-08
        • 2015-08-21
        • 1970-01-01
        • 2016-01-21
        • 1970-01-01
        • 1970-01-01
        • 2021-06-26
        相关资源
        最近更新 更多