代码之家  ›  专栏  ›  技术社区  ›  Christopher Dolan

确定字符串是ANSI C中的整数还是浮点

  •  9
  • Christopher Dolan  · 技术社区  · 16 年前

    仅使用ANSIC,以公平的确定性,确定C样式字符串是整数还是实数(即float/double)的最佳方法是什么?

    9 回复  |  直到 10 年前
        1
  •  35
  •   Patrick_O    11 年前

    不要使用ATOI和ATOF,因为这些函数在失败时返回0。上次我检查0时,它是一个有效的整数和浮点,因此没有用于确定类型。

    使用strto_l、ul、ul l、l l、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)
    

    多亏了乔纳森·莱弗勒指出我忘了先把errno设为0。

        2
  •  9
  •   Patrick    16 年前

    使用 sscanf ,您可以确定字符串是float或int或其他类型的字符串,而不必使用特殊情况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.
      ...
    
        3
  •  3
  •   itsmatt    16 年前

    如果不能,ATOI和ATOF将转换或返回0。

        4
  •  3
  •   Jonathan Leffler    16 年前

    我同意Patrick_o的观点,strto_l、ul、ul l、l l、d函数是最好的方法。不过还有几点值得注意。

    1. 在调用函数之前,将errno设置为零;没有函数为您这样做。
    2. 打开的组页面链接到(我在注意到Patrick也链接到它之前已经访问过)指出,可能没有设置errno。如果值超出范围,则将其设置为Erage;它 可以 被设定(但同样, 可以 如果参数无效,则设置为einval。

    根据手头的作业,有时我会安排跳过转换指针返回的结尾处的尾随空格,然后在最后一个字符不是终止的空值'\0'时抱怨(拒绝)。或者我可以马虎,让垃圾出现在末尾,或者我可以接受可选的乘法器,比如k、m、g、t,用于千字节、兆字节、千兆字节、兆字节等等。或基于上下文的任何其他要求。

        5
  •  2
  •   nutbar    16 年前

    我想你可以跨过绳子,看看有没有 . 其中的字符。不过,这只是第一件突然出现在我脑海中的事情,所以我确信还有其他更好的方法可以更确定。

        6
  •  2
  •   Steve Jessop    16 年前

    使用strtol/strtoll(非atoi)检查整数。 使用strtof/strtod(非atof)检查双精度。

    ATOI和ATOF转换字符串的初始部分,但不要告诉您它们是否使用了所有字符串。strtol/strtod告诉您字符转换后是否有多余的垃圾。

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

    还要注意strod/strtol跳过了初始空白,因此如果要将初始空白的字符串视为格式错误,还需要检查第一个字符。

        7
  •  1
  •   Vincent Robert    16 年前

    这真的取决于你一开始问的原因。

    如果您只想解析一个数字,不知道它是一个浮点还是一个整数,那么只需解析一个浮点,它就可以正确地解析一个整数。

    如果你真的想知道类型,也许是为了分类,那么你真的应该考虑按照你认为最相关的顺序测试类型。比如尝试解析一个整数,如果不能,那么尝试解析一个浮点。(另一种方法只会产生更多的浮点数…)

        8
  •  1
  •   Russ Ryan    16 年前

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

        9
  •  0
  •   falsetru    10 年前

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

    if(atof(token) != NULL || strcmp(token, "0") == 0)