【问题标题】:strtod accepts "e" but also "d" -- why?strtod 接受“e”但也接受“d”——为什么?
【发布时间】:2011-09-07 04:15:51
【问题描述】:

我觉得这很奇怪。

虽然 strtod 接受“e”作为输入字符串中的字符之一(准确地说是一个)是有道理的,但我发现它也接受“d”。

谁能解释一下?

#include < stdio.h >
#include < stdlib.h >
int main ()
{
char *s[] = {"1a1", "1e1", "1d1", "1f1"};
char * pEnd;
double d0, d1, d2, d3;
d0 = strtod (s[0],&pEnd);
d1 = strtod (s[1],NULL);
d2 = strtod (s[2],NULL);
d3 = strtod (s[3],NULL);
printf ("::: [%f] [%f] [%f] [%f] \n", d0, d1, d2, d3);
return 0;
}

【问题讨论】:

标签: c strtod


【解决方案1】:

“接受”是什么意思?这是我得到的输出

::: [1.000000] [10.000000] [1.000000] [1.000000]

strtod(与 C 中的所有其他转换例程一样)解析字符串,直到找到“不属于”的字符。该字符不被视为错误,它只是被视为终止符。在"1d1" 的情况下,仅解析第一个"1" 并且解析在'd' 处停止。转换的结果是1.0(应该是这样)。

如果您要求 strtod 从每个调用中返回“结束指针”,您会看到指针指向字符 'd' 用于其中包含 'd' 的输入字符串(同样适用于 @987654330 @ 和 'f' 也是如此)。

如果你得到不同的结果,那一定是你正在使用的实现的怪癖。

【讨论】:

  • 好吧,当我使用 gcc 和 libc 时,这正是我所观察到的,但 Visual Studio (cl.exe) 和相应的库面临问题。似乎 Microzoft 记录了 'd' 和 'D' 也支持标记双精度。
【解决方案2】:

您使用什么编译器/库来编译此代码?假设您使用的是 Visual Studio,这种行为是预期的(引用 MSDN 中的文本):

strtod 期望 nptr 指向一个 以下形式的字符串:

[空格] [符号] [数字] [.digits] [ {d | D |电子| E}[符号]数字]

您可以找到strtod here 的完整文档

该库的其他实现可能会支持类似的东西。但是,找到herestrtod 的手册页并未说明d 被识别为用于转换目的的有效字符。在这种情况下,它将导致输入字符串的解析停止,并且只有在该点之前解析的字符才会被转换(包含af 的字符串也会发生同样的情况)。

也许您应该查看您的库实现的文档并找出strtod 能够针对您的具体情况解析的格式。

【讨论】:

  • 正是如此。我忘了提供编译器信息。
【解决方案3】:

使用 D 而不是 E 是 Fortran 标记 double 数据(而不是 float)的方法。您可能正在使用接受它作为扩展的标准库。

【讨论】:

  • 请注意,这样的扩展是不合规且危险的。 strtod 的行为是由标准非常严格地规定的,它需要在任何不匹配的字符上停止。
  • 谢谢.. 这可能是支持 'd' 的原因 | 'D' 作为 strtod 的有效字符。
【解决方案4】:

哪个平台和编译器?在 Linux 和 Mac OS X 中我都得到了这个结果:

::: [1.000000] [10.000000] [1.000000] [1.000000]

这意味着只有e 有效。请注意,您没有检查错误...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 2020-11-12
    • 2022-01-22
    相关资源
    最近更新 更多