使用仅限ANSI C,最好的方法是如何以公正的确定性确定C样式字符串是整数还是实数(即float/double)?
使用仅限ANSI C,最好的方法是如何以公正的确定性确定C样式字符串是整数还是实数(即float/double)?
#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。
int i;
float f;
if(sscanf(str, "%d", &i) != 0) //It's an int.
...
if(sscanf(str "%f", &f) != 0) //It's a float.
...
sscanf
的返回值与字符串长度是行不通的,因为它返回成功转换的项目数,而不是用于转换的字符数。但 %n
格式在这里可能有帮助。 - Jensatoi和atof会在无法转换时返回0。
我想你可以逐个检查字符串,并检查其中是否有任何.
字符。尽管这只是我脑海中想到的第一件事,但我相信还有其他更好的方法来更加确定。
这真的取决于你为什么首先提出这个问题。
如果你只想解析一个数字,而不知道它是浮点数还是整数,那么只需解析一个浮点数,它将正确地解析一个整数。
如果你实际上想知道类型,可能是为了分类,那么你应该考虑按照你认为最相关的顺序测试类型。比如尝试解析一个整数,如果不能,则尝试解析一个浮点数。(反过来会产生更多的浮点数...)
atoi和atof会转换数字,即使有尾随的非数字字符。然而,如果您使用strtol和strtod,它不仅会跳过前导空格和可选符号,而且会留下一个指向不在数字中的第一个字符的指针。然后,您可以检查其余部分是否为空格。
如果你不想使用像strtoul这样的新函数,你可以添加另一个strcmp语句来查看字符串是否为0。
例如:
if(atof(token) != NULL || strcmp(token, "0") == 0)
errno
是一个宏,它扩展为可修改的lvalue。通常情况下,它会扩展为(*__errno_location())
或类似的内容。 - R.. GitHub STOP HELPING ICE