strtod not recognizing inf

409 Views Asked by At

I have the following code:

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;
    }
}

the value of input came from strtok() and was passed into the check_for_non_number function...

The problem is when strtok reads "inf" from the text file, my function returns 1, implying the first argument was true... For clarity, the "inf" in the text file is located in the middle of the line in the text file so there is text before and after it and strtok is being used before and after it.

If anyone could shed some light on why strtod() is not handling "inf" as an input to that would be greatly appreciated!

1

There are 1 best solutions below

5
On

The C11 standard requires strtod() to recognize INF:

The expected form of the subject sequence is an optional plus or minus sign, then one of the following:

  • a nonempty sequence of decimal digits optionally containing a decimal-point character, then an optional exponent part as defined in 6.4.4.2;
  • a 0x or 0X, then a nonempty sequence of hexadecimal digits optionally containing a decimal-point character, then an optional binary exponent part as defined in 6.4.4.2;
  • INF or INFINITY, ignoring case
  • NAN or NAN(n-char-sequenceopt), ignoring case in the NAN part, where:

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

The subject sequence is defined as the longest initial subsequence of the input string, starting with the first non-white-space character, that is of the expected form. The subject sequence contains no characters if the input string is not of the expected form.

If you can demonstrate (by calling your function with strings such as "inf") that it fails to convert that to an infinity, then you have a bug in the strtod() provided by your implementation — or it conforms to C90 but not C99 or later. The C90 specification for strtod() did not mention the hex formats (those were added to the language in C99), nor the infinities or NaN handling. From C99 onwards, support for those notations is required.

If you're stuck with a C90 runtime library, you'll have to upgrade to a newer version with the support, or implement your own variant of strtod(), or co-opt an open source implementation. Be wary of how much extra support code an open source implementation also requires for handling locales properly, etc.

Note that the Microsoft Visual Studio 2017 runtime appears to support the C11 specification of strtod(), as does the 2015 version (which is the earliest available on the Microsoft Docs web site). If you're using a significantly older version of MSVS, an upgrade is in order.