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