我希望endptr
与strtod()
和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
答案 0 :(得分: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标准库中的一个错误。
答案 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
之后的数字部分为零长度,因此它不是有效的指数部分。