仅使用 ANSI C,可以相当确定地确定 C 样式字符串是整数还是实数(即浮点数/双精度数)的最佳方法是什么?

有帮助吗?

解决方案

不要使用 atoi 和 atof,因为这些函数在失败时返回 0。上次我检查 0 是有效的整数和浮点数,因此无法用于确定类型。

使用 strto{l,ul,ull,ll,d} 函数,因为这些函数在失败时设置 errno,并且还报告转换后的数据结束的位置。

斯特图尔: http://www.opengroup.org/onlinepubs/007908799/xsh/strtoul.html

此示例假设字符串包含要转换的单个值。

#include <errno.h>

char* to_convert = "some string";
char* p = to_convert;
errno = 0;
unsigned long val = strtoul(to_convert, &p, 10);
if (errno != 0)
    // conversion failed (EINVAL, ERANGE)
if (to_convert == p)
    // conversion failed (no characters consumed)
if (*p != 0)
    // conversion failed (trailing data)

感谢 Jonathan Leffler 指出我忘记先将 errno 设置为 0。

其他提示

使用 扫描仪, ,您可以确定字符串是浮点型还是整数型或其他类型,而不必使用特殊情况 0,就像 atoi 和 atof 解决方案的情况一样。

这是一些示例代码:

int i;
float f;
if(sscanf(str, "%d", &i) != 0) //It's an int.
  ...
if(sscanf(str "%f", &f) != 0)  //It's a float.
  ...

atoi 和 atof 将转换或返回 0(如果不能)。

我同意 Patrick_O 的观点,即 strto{l,ul,ull,ll,d} 函数是最好的方法。不过,有几点需要注意。

  1. 在调用函数之前将 errno 设置为零;没有任何函数可以为你做到这一点。
  2. 链接到的“开放组”页面(我在注意到帕特里克也链接到它之前访问过该页面)指出可能未设置 errno。如果值超出范围,则设置为 ERANGE;它 可能 被设置(但同样, 可能 不是 如果参数无效,则将其设置为 EINVAL。

根据手头的工作,我有时会安排跳过返回的转换指针末尾的尾随空白,然后如果最后一个字符不是终止空“\0”,则抱怨(拒绝)。或者我可以马虎,让垃圾出现在最后,或者我可以接受可选的乘数,如“K”,“M”,“G”,“T”代表千字节,兆字节,千兆字节,太字节,...或基于上下文的任何其他要求。

我想你可以单步遍历字符串并检查是否有 . 其中的人物。但这只是我脑海中闪现的第一件事,所以我确信还有其他(更好)的方法可以更加确定。

使用 strtol/strtoll (不是 atoi)检查整数。使用 strtof/strtod (不是 atof)来检查双打。

atoi 和 atof 转换字符串的初始部分,但不告诉您它们是否使用了整个字符串。strtol/strtod 告诉你字符转换后是否有多余的垃圾。

因此,在这两种情况下,请记住传递一个非空的 TAIL 参数,并检查它是否指向字符串的末尾(即 **TAIL == 0)。还要检查返回值是否下溢和溢出(有关详细信息,请参阅手册页或 ANSI 标准)。

另请注意,strod/strtol 会跳过初始空格,因此如果您想将具有初始空格的字符串视为格式错误,您还需要检查第一个字符。

这实际上取决于您首先问的原因。

如果你只是想解析一个数字,并且不知道它是浮点数还是整数,那么只要解析浮点数,它也会正确解析整数。

如果您确实想了解类型,也许是为了分类,那么您应该真正考虑按照您认为最相关的顺序测试类型。就像尝试解析整数,如果不能,则尝试解析浮点数。(反过来只会产生更多的浮动......)

即使有尾随非数字字符,atoi 和 atof 也会转换数字。但是,如果您使用 strtol 和 strtod,它不仅会跳过前导空格和可选符号,还会为您留下一个指向不在数字中的第一个字符的指针。然后你可以检查其余部分是否是空格。

好吧,如果您不想使用像 strtoul 这样的新函数,您可以添加另一个 strcmp 语句来查看字符串是否为 0。

IE。

if(atof(token) != NULL || strcmp(token, "0") == 0)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top