Exemple #1
0
/**
 * Converts ASCII string to floating point number using specified delimiter.
 *
 * This function converts the initial portion of the string pointed to
 * by nptr to single floating point representation. This function does the
 * same as standard strtof(3), but does not take locale in account. Instead of
 * locale defined decimal delimiter you can specify your own one. Also see
 * notes for CPLAtof() function.
 *
 * @param nptr Pointer to string to convert.
 * @param endptr If is not NULL, a pointer to the character after the last
 * character used in the conversion is stored in the location referenced
 * by endptr.
 * @param point Decimal delimiter.
 *
 * @return Converted value, if any.
 */
float CPLStrtofDelim(const char *nptr, char **endptr, char point)
{
#if defined(HAVE_STRTOF)
/* -------------------------------------------------------------------- */
/*  We are implementing a simple method here: copy the input string     */
/*  into the temporary buffer, replace the specified decimal delimiter  */
/*  with the one, taken from locale settings and use standard strtof()  */
/*  on that buffer.                                                     */
/* -------------------------------------------------------------------- */

    double      dfValue;
    int         nError;

    char*       pszNumber = CPLReplacePointByLocalePoint(nptr, point);

    dfValue = strtof( pszNumber, endptr );
    nError = errno;

    if ( endptr )
        *endptr = (char *)nptr + (*endptr - pszNumber);

    if (pszNumber != (char*) nptr)
        CPLFree( pszNumber );

    errno = nError;
    return dfValue;

#else

    return (float)CPLStrtodDelim(nptr, endptr, point);

#endif /* HAVE_STRTOF */
}
Exemple #2
0
/**
 * Converts ASCII string to floating point number using specified delimiter.
 *
 * This function converts the initial portion of the string pointed to
 * by nptr to double floating point representation. This function does the
 * same as standard strtod(3), but does not take locale in account. Instead of
 * locale defined decimal delimiter you can specify your own one. Also see
 * notes for CPLAtof() function.
 *
 * @param nptr Pointer to string to convert.
 * @param endptr If is not NULL, a pointer to the character after the last
 * character used in the conversion is stored in the location referenced
 * by endptr.
 * @param point Decimal delimiter.
 *
 * @return Converted value, if any.
 */
double CPLStrtodDelim(const char *nptr, char **endptr, char point)
{
    while( *nptr == ' ' )
        nptr ++;

    if (nptr[0] == '-')
    {
        if (strcmp(nptr, "-1.#QNAN") == 0 ||
                strcmp(nptr, "-1.#IND") == 0)
            return NAN;

        if (strcmp(nptr,"-inf") == 0 ||
                strcmp(nptr,"-1.#INF") == 0)
            return -INFINITY;
    }
    else if (nptr[0] == '1')
    {
        if (strcmp(nptr, "1.#QNAN") == 0)
            return NAN;
        if (strcmp (nptr,"1.#INF") == 0)
            return INFINITY;
    }
    else if (nptr[0] == 'i' && strcmp(nptr,"inf") == 0)
        return INFINITY;
    else if (nptr[0] == 'n' && strcmp(nptr,"nan") == 0)
        return NAN;

    /* -------------------------------------------------------------------- */
    /*  We are implementing a simple method here: copy the input string     */
    /*  into the temporary buffer, replace the specified decimal delimiter  */
    /*  with the one, taken from locale settings and use standard strtod()  */
    /*  on that buffer.                                                     */
    /* -------------------------------------------------------------------- */
    double      dfValue;
    int         nError;

    char*       pszNumber = CPLReplacePointByLocalePoint(nptr, point);

    dfValue = strtod( pszNumber, endptr );
    nError = errno;

    if ( endptr )
        *endptr = (char *)nptr + (*endptr - pszNumber);

    if (pszNumber != (char*) nptr)
        CPLFree( pszNumber );

    errno = nError;
    return dfValue;
}
Exemple #3
0
/**
 * Converts ASCII string to floating point number using specified delimiter.
 *
 * This function converts the initial portion of the string pointed to
 * by nptr to double floating point representation. This function does the
 * same as standard strtod(3), but does not take locale in account. Instead of
 * locale defined decimal delimiter you can specify your own one. Also see
 * notes for CPLAtof() function.
 *
 * @param nptr Pointer to string to convert.
 * @param endptr If is not NULL, a pointer to the character after the last
 * character used in the conversion is stored in the location referenced
 * by endptr.
 * @param point Decimal delimiter.
 *
 * @return Converted value, if any.
 */
double CPLStrtodDelim(const char *nptr, char **endptr, char point)
{
    while( *nptr == ' ' )
        nptr ++;

    if (nptr[0] == '-')
    {
        if (strcmp(nptr, "-1.#QNAN") == 0 ||
            strcmp(nptr, "-1.#IND") == 0)
        {
            if( endptr ) *endptr = (char*)nptr + strlen(nptr);
            // While it is possible on some platforms to flip the sign
            // of NAN to negative, this function will always return a positive
            // quiet (non-signalling) NaN.
            return std::numeric_limits<double>::quiet_NaN();
        }

        if (strcmp(nptr,"-inf") == 0 ||
            STARTS_WITH_CI(nptr, "-1.#INF"))
        {
            if( endptr ) *endptr = (char*)nptr + strlen(nptr);
            return -std::numeric_limits<double>::infinity();
        }
    }
    else if (nptr[0] == '1')
    {
        if (strcmp(nptr, "1.#QNAN") == 0)
        {
            if( endptr ) *endptr = (char*)nptr + strlen(nptr);
            return std::numeric_limits<double>::quiet_NaN();
        }
        if( STARTS_WITH_CI(nptr, "1.#INF") )
        {
            if( endptr ) *endptr = (char*)nptr + strlen(nptr);
            return std::numeric_limits<double>::infinity();
        }
    }
    else if (nptr[0] == 'i' && strcmp(nptr,"inf") == 0)
    {
        if( endptr ) *endptr = (char*)nptr + strlen(nptr);
        return std::numeric_limits<double>::infinity();
    }
    else if (nptr[0] == 'n' && strcmp(nptr,"nan") == 0)
    {
        if( endptr ) *endptr = (char*)nptr + strlen(nptr);
        return std::numeric_limits<double>::quiet_NaN();
    }

/* -------------------------------------------------------------------- */
/*  We are implementing a simple method here: copy the input string     */
/*  into the temporary buffer, replace the specified decimal delimiter  */
/*  with the one, taken from locale settings and use standard strtod()  */
/*  on that buffer.                                                     */
/* -------------------------------------------------------------------- */
    char* pszNumber = CPLReplacePointByLocalePoint(nptr, point);

    const double dfValue = strtod( pszNumber, endptr );
    const int nError = errno;

    if ( endptr )
        *endptr = (char *)nptr + (*endptr - pszNumber);

    if (pszNumber != (char*) nptr)
        CPLFree( pszNumber );

    errno = nError;
    return dfValue;
}