4

我希望 和都endptr指向相同的值。然而它们不同。我怀疑是不正确的。OTOH,这可能是规格不明确且任一结果都可接受的情况。strtod()strtold()strtold()

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

使用: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 命令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

4

2 回答 2

4

也不应该消耗e. 要被允许使用e, 之后必须有一个非空的数字序列e。带有 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 标准库中的错误。

于 2015-03-13T19:29:58.953 回答
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 的主题序列;以及一个或多个无法识别的字符的最终字符串,包括输入字符串的终止空字符。然后,他们尝试将主题序列转换为浮点数,并返回结果。

并且主题序列被定义:

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

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

于 2015-03-13T19:43:32.287 回答