3

我有以下代码:

int check_for_non_number(char *input, int lineNum)
{
    errno = 0;
    char *endptr;
    printf("%s\n",input);
    double xnum = strtod(input, &endptr);
    // IF endptr FOUND A NON-VALID ENTRY AND THAT ENTRY IS NOT THE NEW LINE CHARACTER THEN ITS AN ERROR
    if((*endptr) && (*endptr != '\n'))
    {
        return 1;
    }
    // We still want to process this number, even if it is represented as inf, so inform the user in the terminal and then return 0
    else if (errno == ERANGE)
    {
        printf("\nOPERAND IS OUT OF RANGE ON LINE %d\n",lineNum);
        return 0;
    }
    // ELSE IF endptr FOUND A NON-VALID ENTRY AND THAT ENTRY IS THE NEW LINE CHARACTER THEN RETURN 2 TO CHECK IF IT SHOULD BE A NEW LINE
    else if((*endptr) && (*endptr == '\n'))
    {
        return 2;
    }
    else
    {
        return 0;
    }
}

的值input来自strtok()并被传递到check_for_non_number函数中......

问题是当 strtok 从文本文件中读取“inf”时,我的函数返回 1,暗示第一个参数为真……为清楚起见,文本文件中的“inf”位于文本行的中间文件,因此在它之前和之后都有文本,并且在它之前和之后都使用了 strtok。

如果有人能阐明为什么strtod()不将“inf”作为输入来处理,将不胜感激!

4

1 回答 1

1

C11 标准要求strtod()识别INF

主题序列的预期形式是可选的加号或减号,然后是以下之一:

  • 一个非空的十进制数字序列,可选地包含一个小数点字符,然后是 6.4.4.2 中定义的可选指数部分;
  • 一个 0x 或 0X,然后是可选包含小数点字符的十六进制数字的非空序列,然后是 6.4.4.2 中定义的可选二进制指数部分;
  • INF 或 INFINITY,忽略大小写
  • NAN 或 NAN(n-char-sequence opt ),忽略 NAN 部分的大小写,其中:

     n-char-sequence:
             digit
             nondigit
             n-char-sequence digit
             n-char-sequence nondigit
    

主题序列被定义为输入字符串的最长初始子序列,从第一个非空白字符开始,即具有预期形式。如果输入字符串不是预期的形式,则主题序列不包含字符。

如果您可以证明(通过使用诸如 之类的字符串调用您的函数"inf")它无法将其转换为无穷大,那么您的strtod()实现中提供了一个错误 - 或者它符合 C90 但不符合 C99 或更高版本。C90 规范strtod()没有提到十六进制格式(这些是在 C99 中添加到语言中的),也没有提到无穷大或 NaN 处理。从 C99 开始,需要支持这些符号。

如果您被 C90 运行时库困住了,您将不得不升级到具有支持的新版本,或者实现您自己的变体strtod(),或者选择开源实现。请注意开源实现还需要多少额外的支持代码才能正确处理语言环境等。

请注意,Microsoft Visual Studio 2017 运行时似乎支持 的 C11 规范strtod(),2015 版本(这是 Microsoft Docs 网站上最早可用的版本)也是如此。如果您使用的是旧版本的 MSVS,则需要升级。

于 2019-03-13T06:04:11.407 回答