LynxOS strtod 与 Linux 不一样

Posted

技术标签:

【中文标题】LynxOS strtod 与 Linux 不一样【英文标题】:LynxOS strtod not the same as Linux 【发布时间】:2010-12-11 21:21:54 【问题描述】:

似乎 LynxOS 的strtod 实现并不能处理与 Linux 或 Solaris 相同的所有情况。我遇到的问题是我正在尝试解析一些可以包含十进制或十六进制数字的文本。

在 Linux 上我调用

a = strtod(pStr, (char **)NULL);

我在a 中得到了1.2345670x40 等输入字符串的预期值。

在 LynxOS 上,十进制数字解析正确,但十六进制解析为 0,因为它在碰到“x”时停止。查看手册页,似乎 LynxOS 的 strtod 只支持输入中的十进制字符串。

这里有人知道可以在 Lynx 和 Linux 上运行的替代方案吗?

【问题讨论】:

欢迎来到 Unix 的土地。如果您写入(其中一个)POSIX 标准,您将获得更多的可移植性。但这可能意味着忽略一些非常有用的扩展。 @dmckee:这与 UNIX 无关。它与 OP 通过调用具有错误签名的函数来调用 UB 有关。所需的行为甚至不是 POSIX 特定的;这是 ANSI/ISO C 要求的。 @R.. 甚至没看那个。刚刚回应了系统依赖的说法。 @R..:问题中指定的调用绝对没有问题。 “错误的签名”是什么意思。 @R.. 签名怎么错了? 【参考方案1】:

引用标准 (7.20.1.3) (http://www.open-std.org/JTC1/sc22/wg14/www/docs/n1256.pdf)

主题序列的预期形式是可选的加号或减号,然后是其中之一 以下: — 一个非空的十进制数字序列,可选地包含一个小数点 字符,然后是 6.4.4.2 中定义的可选指数部分; — 一个 0x 或 0X,然后是一个非空的十六进制数字序列,可选地包含一个 小数点字符,然后是 6.4.4.2 中定义的可选二进制指数部分; — [...]

所以,您在 LynxOS 上使用的编译器不是 C99 编译器。


我的 C89 标准副本没有引用 0x 前缀:

4.10.1.4 strtod 函数

[...]

主题序列的预期形式是可选的加号或 减号,然后是一个非空的数字序列,可选地包含一个 小数点字符,然后是可选的指数部分 [...]

【讨论】:

编译器为GCC,版本3.2.2,由LynuxWorks提供。 嗯 ...我的答案已编辑以反映 C99。据我所知(我的 C89 标准版本不可信),C89 不需要0x 我想我需要查看 3.2.2 是否符合 C99 或只是 C89 @LordOphidian:在这种情况下,感兴趣的不是 GCC,而是您正在使用的 C 库(@​​987654328@ 不是由 GCC 实现的)。【参考方案2】:

strtod 接受 3 个参数,而不是两个。如果您通过包含正确的标头 (stdlib.h) 对其进行了原型设计,那么您的编译器会发出错误。由于您正在调用具有错误签名的函数,因此您的程序具有未定义的行为。解决这个问题,一切都会好起来的。

【讨论】:

我想你的意思是strtol和朋友们 -1 不正确,strtod 具有以下原型:double strtod(const char * restrict nptr, char ** restrict endptr); - 直接取自 C99 标准。 确实,我误读并认为问题是关于strtol。对于它的价值,C99 需要 strtod 来支持十六进制浮点数(如果我没记错的话,这需要一个指数)但 C89 不支持,因为它们在 C89 中不存在。

以上是关于LynxOS strtod 与 Linux 不一样的主要内容,如果未能解决你的问题,请参考以下文章

使用 Visual Studio 2005 构建 LynxOS 应用程序

c语言strtod()函数的用法

OS history

`strtod("3ex", &end)` 的结果应该是啥? `sscanf` 呢?

strtok() and strtod()

c_cpp 在const char **中使用strtod