sscanf(" 0X80.9","%f",& value)将值设置为十六进制浮点数而非浮点数

时间:2017-11-23 23:22:04

标签: c scanf format-specifiers

我有一些读取字母值对的代码。它可以简化为:

float value = 0.0;
sscanf("0X80.9", "%f", &value);

在Visual Studio 2013中,value = 0

在Visual Studio 2015及更高版本中,值= 128.5625(即十六进制为0x80 =十进制为128)

任何人都知道为什么会发生这种变化?更重要的是,任何人都知道如何让它像过去一样工作?

2 个答案:

答案 0 :(得分:4)

C99添加了一个新功能,十六进制浮点常量。它还为*scanf()函数添加了新格式。 (源代码中的十六进制浮点常量必须具有指数部分;对于scanf,指数是可选的。)

scanf读取尽可能多的输入,因为它与格式一致。对于1999年之前的C,这是最初的"0";剩下以下"X80.9"。对于C99,"0X80.9"有效,并转换为浮点值128.5625。 (格式与strtof()接受的格式相同。)

C ++标准通过引用包含大部分C标准库。直到c ++ 2012,它才更新到C库的C99版本。

最有可能Visual Studio 2015支持C ++ 12或更高版本,而Visual Studio 2013则不支持。

由于新行为现在已成为标准,我建议您调整代码来处理它,而不是试图强制旧行为。如果有办法让VS2015以旧的方式运行,那么应该记录下来。

答案 1 :(得分:1)

在1999 C标准中,添加了strtod的输入(这是scanf中引用的%f)可以包含0x0X前缀表示十六进制浮点数。

16年后,微软似乎终于开始做这项工作了。

您最好的选择是继续使用新行为,而不是尝试调用编译器标志来获取旧行为(这可能是不可能的,我不知道)。

要模拟项目中的旧行为,您可以使用以下代码:

double my_scan(char const *s)
{
    double value = 0.0;

    if ( ! memcmp(s, "0X", 2) )
         sscanf(s, "%f", &value);

    return value;
}

或任何适合您用例的内容。也许你最终可能会编写自己的标记器。