带有strtod()/ strtold()的意外的endptr

时间:2015-03-13 19:26:23

标签: c gcc strtod

我希望endptrstrtod()strtold()指向相同的值。但他们不同。我怀疑strtold()不正确。 OTOH,这可能是规范不明确且结果不可接受的情况。

这是一个错误(以及哪个函数)或未定义/未指定的行为?

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

#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

2 个答案:

答案 0 :(得分:4)

也不应该使用e。要允许使用ee后必须有一个非空数字序列。带有Glibc 2.12的GCC 4.9.0表现正常。

[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和strtold函数

     

主题序列的预期形式是可选的加号或减号,然后是以下之一:

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

第6.4.4.2节浮动常量

exponent-part:
    e signopt digit-sequence
    E signopt digit-sequence
digit-sequence:
    digit
    digit-sequence digit

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

答案 1 :(得分:3)

这是strtold的错误 - 标准将常量的指数部分的语法定义为(6.4.4.2):

exponent-part:
    e sign(optional) digit-sequence
    E sign(optional) digit-sequence

其中:

digit-sequence:
    digit
    digit-sequence digit

定义digit以使其不能为零长度。因此,e之后的数字部分不能为零长度。

strtold的行为被定义(强调我的):

  

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

主题序列定义如下:

  

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

由于示例中e之后的数字部分为零长度,因此它不是有效的指数部分。