首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用strtod()/strtold()的意外endptr

使用strtod()/strtold()的意外endptr
EN

Stack Overflow用户
提问于 2015-03-13 19:26:22
回答 2查看 344关注 0票数 4

我希望endptr指向与strtod()strtold()相同的值。然而,他们的观点不同。我怀疑strtold()是错误的。OTOH,这可能是一种情况,规格是不明确的,任何一个结果是可以接受的。

这是bug (以及使用哪个函数)还是未定义/未指定的行为?

用途: gcc\x86_64-pc-cygwin\4.8.3

代码语言:javascript
复制
#include <math.h>
#include <stdio.h>

// Edit - This include is in my true code, but was missing in original post
#include <stdlib.h>

int main(void) {
    char *s = "123ez";
    char *endptr;
    double d = strtod(s, &endptr);
    printf("     double %f '%s'\n", d, endptr);
    long double ld = strtold(s, &endptr);
    printf("long double %Lf '%s'\n", ld, endptr);
    return 0;
    }

Output:
     double 123.000000 'ez'
long double 123.000000 'z'

编辑

gcc comand gcc -I"C:\cygwin64\lib\gcc\x86_64-pc-cygwin\4.8.3\include" -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -MMD -MP -MF"string_fp.d" -MT"string_fp.d" -o "string_fp.o" "../string_fp.c"

GCC 4.9.2

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-13 19:29:58

两者都不应该使用e。要允许使用e,必须在e之后有一个非空的数字序列。GCC 4.9.0和Glibc 2.12的行为正确。

代码语言:javascript
复制
[2:29pm][wlynch@apple /tmp] ./a.out 
     double 123.000000 'ez'
long double 123.000000 'ez'

引用了C 2011标准草案N1570的一些内容.

第7.22.1.3节第3段: strtod、strtof和strtod函数 主题序列的预期形式是可选的正负号,然后是下列之一:

  • 一个非空的十进制数字序列,可选地包含一个小数点字符,然后是6.4.4.2中定义的可选指数部分;
  • ..。

第6.4.4.2节浮动常数

指数-部分:e-符号数字-序列E符号选择数字-序列数字-序列:数字-序列数字数字

我认为这是您正在运行的C标准库中的一个错误。

票数 4
EN

Stack Overflow用户

发布于 2015-03-13 19:43:32

它是strtold的一个bug --标准将常量的指数部分的语法定义为(6.4.4.2):

代码语言:javascript
复制
exponent-part:
    e sign(optional) digit-sequence
    E sign(optional) digit-sequence

其中:

代码语言:javascript
复制
digit-sequence:
    digit
    digit-sequence digit

digit的定义使得它不能是零长度。所以e后面的数字部分不能是零长度。

定义了strtold的行为(重点是地雷):

strtod、strtof和strtod函数分别将nptr指向的字符串的初始部分转换为double、float和long double表示。首先,它们将输入字符串分解为三个部分:初始(可能是空的)空白字符序列(如isspace函数指定的)、(类似浮点常量或表示无穷大或NaN)的主题序列;以及一个或多个未识别字符的最后字符串,包括输入字符串的终止空字符。然后,他们尝试将主题序列转换为浮点数,并返回结果.

并定义了主题序列:

一个非空的十进制数字序列,可选地包含一个小数点字符,然后是6.4.4.2中定义的可选指数部分。

因为在你的例子中,e后面的数字部分是零长度,所以它不是有效的指数部分。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29040427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档