【问题标题】:scanf with precision specifier parameter带有精度说明符参数的 scanf
【发布时间】:2015-04-14 14:38:22
【问题描述】:

刚开始学C,因为把scanf和printf混在一起,一不小心写了这样的代码:

    float loan = 0.0f; // loan
    float rate = 0.0f; // monthly interest rate
    float mpay = 0.0f; // monthly pay

    printf("Enter amount of loan: ");
    scanf("%.2f",&loan); // I am supposed to write scanf("%f",&loan),  I was trying to take a float input with two digits after point

    printf("Enter interest rate: ");
    scanf("%.2f",&rate); // similar here

    printf("Enter monthly payment: ");
    scanf("%.2f",&mpay); // similar here

我希望这段代码会显示三个输入提示,每个提示都会挂起并在那里等待,直到我输入一些输入并按 Enter 键。但是发生的情况是,只有第一个提示在等待我的输入,然后当我按下回车键时,第二个和第三个提示很快就出现了,而无需等待我的输入,就好像代码从其他地方得到了我的输入一样。后来,当我检查三个应该保存三个输入的变量的值时,它们实际上都没有存储输入值。

我回到我的 C 书并意识到我将printf 的最小字段和精度参数概念与scanf 混合在一起,所以我猜scanf 没有这样的语法?但是如果是这样,那么为什么编译器会编译,这是否意味着 scanf 也存在这样的语法,或者我对此有误?我应该如何解释这种不等待我的第二个和第三个输入并且不将输入存储到三个变量中的奇怪行为?

【问题讨论】:

  • 在所有 3 个 scanfs 之后您是否打印了值?
  • scanf 不包含浮点数精度字段。您的代码不能使用 gcc 编译,并且在删除 .2 时可以正常工作。我无法解释你的行为。

标签: c


【解决方案1】:

是的,C 标准指定的scanf() 系列不支持此功能。这是明确未定义的行为,这意味着 任何事情 都允许发生。

但有些编译器确实会在编译时执行检查格式字符串有效性的警告。 GCC(和 Clang)有 -Wformat(由 -Wall 启用,无论如何都应该使用它)。如果您使用不同的编译器,则必须阅读其文档或使用静态分析工具。

来自 ISO C11 委员会草案 (N1570),7.21.6.2 第 13 段:

如果转换规范无效,则行为未定义。 287)

脚注是指 7.31.11 par。 1:

小写字母可以添加到 fprintf 和 fscanf 中的转换说明符和长度修饰符。扩展名中可以使用其他字符。

所以. 可以通过scanf() 实现作为扩展来支持,尽管我不知道有这样的实现。

【讨论】:

    【解决方案2】:

    在 TC 上运行这段代码,它就按照你说的那样执行了…… 首先,您不应该在 scanf 中包含字段格式说明符。

    在您的情况下,我认为除了 %f 之外您提供的数字(例如 .2 在您的情况下)..因为 scanf 行为异常..您作为输入提供的值可能存储在不同的地址位置(与.2 相关的东西)..因此变量 rate、loan 等没有显示值,因为其中没有存储任何内容。

    【讨论】:

      【解决方案3】:

      您无法转换 scanf 中的精度。如果您使用gcc 编译它,您应该会收到unknown conversion type character ‘.’ in format 警告。

      检查程序的一种方法是打印出scanf 的返回值,你会发现所有这3 个scanf 都给你0,这意味着这3 个变量都没有被扫描到任何值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-21
        • 1970-01-01
        • 1970-01-01
        • 2016-04-04
        • 1970-01-01
        相关资源
        最近更新 更多