在我的实验中,这个表达式
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%lfstrtodscanfscanf%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. 但是语言规范中的所有内容都是这样吗?