【问题标题】:Question about scanf() with lf specifier and printf() with lf specifier?关于带有 lf 说明符的 scanf() 和带有 lf 说明符的 printf() 的问题?
【发布时间】:2011-03-07 02:47:46
【问题描述】:

我正在学习 C 并且我有以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char *argv[])
{
  double x;
  printf("x = ");
  scanf("%ld", &x);
  printf("x = %lf\n", x);

  system("PAUSE");  
  return 0;
}

(我使用的是 Dev C4.9,Windows XP SP3)

当我运行上述程序并进入 5.3;程序打印x = 0.000000

谁能解释一下这是为什么?

非常感谢。

【问题讨论】:

    标签: c printf scanf


    【解决方案1】:

    %ld 格式字符串意味着它期望读取long signed int,但您传递的是double。您应该改用%lf 格式说明符来表示您想要double

    请注意,对于scanfdoubles 需要lfloats 需要不存在),而对于printf%lf 中的l 具有无效:由于默认参数提升,%f%lf 对于 floats 和 doubles 具有相同的输出。

    【讨论】:

    • 感谢您的回答。我知道我添加了错误的说明符。但我想知道 scanf() 是如何工作的,所以它产生了错误的结果。你能详细说明一下吗?
    • @ipkiss:当scanf 读取格式字符串时,它会看到%ld,它告诉它“传递给我的下一个参数必须是long int*。我要将字符串解析为long int,并将解析后的值存储在指向位置的指针中。”因此,它会解析数字“5”并将其存储到 double 变量开头的 4 个字节中。当您使用%ld 时,它会将字符串解析为double,并将值作为double 存储在您想要的指向位置中。
    • @Adam Rosenfield:所以,我认为它会打印出:5.00000 而不是 0.000000。我想错了吗?
    • @ipkiss double 和 long 都作为字节序列存储在内存中,但它们具有不同的长度和表示形式。将 long 存储到用于 double 的内存的一部分中会产生不确定的后果——你不能指望它会导致任何特定的 double 甚至是有效的 double。
    • @Adam 您在评论中的意思是“当您使用 %lf 时”,而不是“... %ld”。
    【解决方案2】:

    为您的scanf ld:

    same as "%d" except argument is "long" integer. Since "long"
    is the same as "int" on GCOS8,this is the same as "%d". However, the compiler 
    will warn you if you specify "%ld" but pass a normal "int", or specify "%d" but 
    pass a "long".
    

    为您的printflf:

    same as "%f" except argument is "long double". 
    Since "long double" is the same as "double" on GCOS8, this is the same as "%f". 
    

    read this.

    【讨论】:

      【解决方案3】:

      与scanf和printf的数据保持一致。 加上 %lf(double)、%f(float)、%lld(long long int) 我在 Windows 中遇到了问题。它在 Windows 中没有很好地实现(如果你问的话是 msvcrt.dll)。

      【讨论】:

        【解决方案4】:

        最好使用gets(),然后尝试将输入的字符串解析并转换为所需的类型。

        因为所有内容最初都是作为字符串输入的,因此更容易处理错误的输入。

        scanf 要求输入是完美的,而这并不总是在人类键入数据时发生。

        【讨论】:

        • 哇!永远不要永远使用gets永远!
        • 这对安全性和速度不利。仅供参考en.wikipedia.org/wiki/C_standard_library#Criticism
        • 你在开玩笑吗?使用gets()从来没有比使用anything更好!
        • 除了gets 制造了一个等待被利用的安全漏洞,而且你的“答案”并没有解决手头的问题,你的评论毫无意义。如果输入无效,则无效,无论您是读取一行(例如,通过fgets)然后解析它(例如,通过sscanf),还是直接通过@987654328读取输入都没有关系@。在处理面向行的输入时,前者通常更容易,但那是另一回事。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-01
        • 2017-11-16
        • 2011-05-23
        • 2014-01-07
        相关资源
        最近更新 更多