C strtod()歧义:格式错误和零转换

C strtod()歧义:格式错误和零转换,c,C,我正在考虑使用函数将C中的字符串转换为double,其符号为: double strtod (const char* str, char** endptr); 是str要转换的字符串和endptr要设置为数字后第一个字符的指针 文件说: 如果成功,函数将转换后的浮点数作为double类型的值返回。 如果无法执行有效转换,则函数返回零(0.0) 因此,据我所知,从str表示0(例如“0”、“0.000”、“-0.0”、“0e10”)的情况中,无法检测到str存在格式错误(例如“foo”、“-3a

我正在考虑使用函数将C中的字符串转换为double,其符号为:

double strtod (const char* str, char** endptr);
str
要转换的字符串和
endptr
要设置为数字后第一个字符的指针

文件说:

如果成功,函数将转换后的浮点数作为double类型的值返回。 如果无法执行有效转换,则函数返回零(0.0)

因此,据我所知,从
str
表示0(例如“0”、“0.000”、“-0.0”、“0e10”)的情况中,无法检测到
str
存在格式错误(例如“foo”、“-3ab”或“3o3”)的情况

如何使用strtod()函数来避免零转换中的问题


编辑:我看到了一个类似的问题。然而,我想我并没有问同样的问题,因为我的问题是关于0和格式错误的字符串之间的歧义问题,而另一篇文章是关于检测一般的格式错误。

这正是为什么你有
endptr
。如果在呼叫后
endptr==str
,则没有解析任何号码。

这正是您拥有
endptr
的原因。如果在调用后
endptr==str
,则未解析任何数字。

此外,如果要检测其他错误,如“3.14xyz”,strod将返回3.14,但endptr将指向“x”,因此,如果在strod之后,“endptr”不指向“str”,而“endptr”仅指向空白(如果您希望严格,则精确为0),那么“str”确实是一个有效的浮点。此外,如果字符串“str”会引发溢出,则errno设置为ERANGE

下面是它的一个实现:

bool isDouble(const char* s)
{
  char* rest = (char*) s;

  strtod(s, &rest);

  if ((rest == s) || (errno == ERANGE))
    return false;

  // If all WS after the last char used in the conversion, then the string is considered a 'clean float'
  while ((*rest == ' ') || (*rest == '\t') || (*rest == '\n'))
    ++rest;

  return (*rest == 0);
}

此外,如果要检测其他错误,如“3.14xyz”,strod将返回3.14,但endptr将指向“x”,因此,如果strod之后的“endptr”不指向“str”,而“endptr”仅指向空白(如果希望严格,则正好是0),那么“str”确实是一个有效的浮点。此外,如果字符串“str”会引发溢出,则errno设置为ERANGE

下面是它的一个实现:

bool isDouble(const char* s)
{
  char* rest = (char*) s;

  strtod(s, &rest);

  if ((rest == s) || (errno == ERANGE))
    return false;

  // If all WS after the last char used in the conversion, then the string is considered a 'clean float'
  while ((*rest == ' ') || (*rest == '\t') || (*rest == '\n'))
    ++rest;

  return (*rest == 0);
}

See和See as
strtol的重复行为类似于
strtod
See和See as
strtol的重复行为类似于
strtod
不确定这在所有情况下是否正确。。。如果
str
是“3ab4”,则str指向3。调用strtod()后,函数返回3(双精度)和
endptr
指向“a”(恰好是数字后的第一个字符),即
str
+1。因此,在这种情况下,存在格式错误,
endptr==str
条件无法检测到它。@fgalan这根本不是格式错误。该函数被定义为解析并返回它所能返回的最大字符数,在本例中,它只是一个字符。@fgalan,如果您想知道整个str是否对结果有贡献(被解析),只需检查
(*endptr==0)
不确定在所有情况下是否正确。。。如果
str
是“3ab4”,则str指向3。调用strtod()后,函数返回3(双精度)和
endptr
指向“a”(恰好是数字后的第一个字符),即
str
+1。因此,在这种情况下,存在格式错误,
endptr==str
条件无法检测到它。@fgalan这根本不是格式错误。该函数被定义为解析并返回它所能返回的最大字符数,在本例中,它只是一个字符。@fgalan,如果您想知道整个str是否对结果有贡献(被解析),只需检查
(*endptr==0)
为什么不使用它来检测空白?因为我从未听说过该函数:-)是,这似乎不是个坏主意。特别是它是作为宏实现的。为什么不使用它来检测空白呢?因为我从来没有听说过这个函数:-)是的,这似乎不是个坏主意。尤其是当它作为宏实现时。