在我的实验中,这个表达式
double d = strtod("3ex", &end);
d
用输入字符串中的字符初始化3.0
并放置end
指针。'e'
这正是我期望它的行为。该'e'
字符可能看起来是指数部分的开始,但由于缺少实际的指数值(6.4.4.2 要求),因此'e'
应将其视为完全独立的字符。
但是,当我这样做时
double d;
char c;
sscanf("3ex", "%lf%c", &d, &c);
我注意到它sscanf
同时消耗'3'
和'e'
用于%lf
格式说明符。变量d
接收3.0
值。变量c
以'x'
in 结尾。这对我来说看起来很奇怪,原因有两个。
首先,由于语言规范在描述格式说明符strtod
的行为时涉及到,我直观地期望以相同的方式处理输入(即选择与终止点相同的位置)。但是,我知道历史上应该不超过一个字符返回输入流。这限制了一个字符可以执行的任何前瞻的距离。上面的例子需要至少两个字符的前瞻。因此,假设我接受了从输入流中消耗和消耗的事实。%f
%lf
strtod
scanf
scanf
%lf
'3'
'e'
但后来我们遇到了第二个问题。现在sscanf
必须将其转换"3e"
为 type double
。"3e"
不是浮点常量的有效表示(同样,根据 6.4.4.2,指数值不是可选的)。我希望sscanf
将此输入视为错误:在%lf
转换期间终止,返回0
和离开d
并 c
保持不变。但是,上述sscanf
成功完成(返回2
)。
这种行为在标准库的 GCC 和 MSVC 实现之间是一致的。
所以,我的问题是,在 C 语言标准文档中,它究竟允许在哪里sscanf
表现如上所述,参考以上两点:消耗更多strtod
并成功地将这样的序列转换为"3e"
?
通过查看我的实验结果,我可能可以“逆向工程”sscanf
的行为:消耗尽可能多的“看起来正确”,从不后退,然后将消耗的序列传递给strtod
. 这种方式'e'
会被 . 消耗%lf
,然后被strtod
. 但是语言规范中的所有内容都是这样吗?