Win7 64-bit
gcc 4.8.2
g++ -Wall
我尝试按照Why does scanf() need "%lf" for doubles, when printf() is okay with just "%f"?中的定义格式化我的C ++ sscanf,但返回值为x == 0.程序如下所示。我无法弄清楚我做错了什么,所以欢迎任何建议。
# include <stdio.h>
# include <ios>
# include <iostream>
# include <iomanip>
#include <cstdlib>
using namespace std;
int main(int argc, char** argv) {
char buffer[30];
double x = 5.0;
sprintf(buffer, "%a", 1.2);
sscanf(buffer, "%la", &x);
cout << " Example 1.2 buffer -> " << buffer << endl;
cout << " Example 1.2 scanf <- " << x << endl;
return 0;
}
输出
Example 1.2 buffer -> 0x1.3333333333333p+0
Example 1.2 scanf <- 0
答案 0 :(得分:1)
我发现您的代码没有任何问题。当我在Linux系统上编译并运行它时,输出为:
Example 1.2 buffer -> 0x1.3333333333333p+0
Example 1.2 scanf <- 1.2
%a
和*printf
函数的*scanf
说明符是在C99中引入的,并且已合并到C ++ 11中。对于sprintf
调用,"%a"
是double
类型参数的有效格式,而sscanf
调用"%la"
是参数的有效格式类型为double*
。
gcc(或g ++)的版本与问题没有直接关系。 gcc只是编译器; sscanf
函数由运行时库实现。
当我在Windows 7上编译并运行Cygwin下的程序时,我得到的输出错误相同。 Cygwin使用&#34; newlib&#34; C库,它与大多数Linux系统上使用的glibc库不同。
如果您正在使用gcc的MinGW安装,如果我没记错,它会使用Microsoft C库。微软在1990年以后对C标准的支持并不好,如果它没有正确实现sscanf
的{{1}}格式,那就太不足为奇了。
请注意,您不需要使用"%la"
进行十六进制输入。对于"%la"
函数,*scanf
,a
,e
和f
说明符都是等效的,并且将接受十进制或十六进制浮点输入。所以你应该可以使用:
g
但如果sscanf(buffer, "%lf", &x);
无法正常工作,"%la"
可能无法正常工作。
"%lf"
函数返回sscanf
结果,表示已成功扫描的项目数。你应该经常检查结果。 (虽然如果我在Cygwin上的实验是任何指南,在这种情况下它不会有任何好处; int
返回sscanf
但仍然将1
设置为x
。 )
结论:您的代码没问题,但您可能正在使用的运行时库不支持您尝试做的事情。
这是另一个程序(它是直接的C但它应该像C ++一样工作),应该提供更多的信息。 0.0
返回写入的字符数; sprintf
返回读取的项目数。
sscanf
在我的Linux系统上,我得到了正确的输出,即:
#include <stdio.h>
int main(void) {
char buffer[40];
char leftover[40];
double x = 5.0;
int sprintf_result = sprintf(buffer, "%a", 1.2);
printf("sprintf returned %d, buffer = \"%s\"\n", sprintf_result, buffer);
int sscanf_result = sscanf(buffer, "%lf%s", &x, leftover);
printf("sscanf returned %d, x = %f", sscanf_result, x);
if (sscanf_result >= 2) {
printf(", leftover = \"%s\"", leftover);
}
putchar('\n');
return 0;
}
在Cygwin下,我得到了这个输出:
sprintf returned 20, buffer = "0x1.3333333333333p+0"
sscanf returned 1, x = 1.200000
表示sprintf returned 20, buffer = "0x1.3333333333333p+0"
sscanf returned 2, x = 0.000000, leftover = "x1.3333333333333p+0"
格式导致"%lf"
只使用sscanf
,其余字符串将被0
使用。这是C90实现的特征(在"%s"
添加到标准之前) - 但"%a"
printf
正常工作。
在您的系统上试试这个。
答案 1 :(得分:0)
sprintf(buffer, "%a", 1.2);
实施例1.2缓冲液 - &gt; 0x1.3333333333333p + 0
%a格式将数字读取为十六进制浮点格式。此格式的数字以
的形式表示0xB.CpN
,其中
这样:
0x1.3333333333333p + 0
代表
1.0011001100110011001100110011001100110011001100110011 x 2 ^ 0
此十六进制格式表示最接近十进制数1.2的双精度浮点数。
关于你的例子中的原因
示例1.2 scanf&lt; - 0
使用gcc 4.7.2编译,这与4.8.1一样正常。问题出在您链接的运行时库中。