37

How can I convert string to double in C++? I want a function that returns 0 when the string is not numerical.

7
  • You should give this a more descriptive title or no one will help. Commented Dec 25, 2008 at 17:18
  • See answers to similar question How to parse a string to an int in C++? Commented Dec 25, 2008 at 17:34
  • 15
    How about some of the examples from the following: codeproject.com/KB/recipes/Tokenizer.aspx They are very efficient and somewhat elegant. Commented Nov 6, 2010 at 6:29
  • 2
    Why return 0 when you could return NaN? Commented Nov 17, 2013 at 0:56
  • 1
    Not a duplicate, this is the opposite operation. Commented May 22, 2014 at 17:33

10 Answers 10

38

See C++ FAQ Lite How do I convert a std::string to a number?

See C++ Super-FAQ How do I convert a std::string to a number?

Please note that with your requirements you can't distinguish all the the allowed string representations of zero from the non numerical strings.

 // the requested function
 #include <sstream>
 double string_to_double( const std::string& s )
 {
   std::istringstream i(s);
   double x;
   if (!(i >> x))
     return 0;
   return x;
 } 

 // some tests
 #include <cassert>
 int main( int, char** )
 {
    // simple case:
    assert( 0.5 == string_to_double( "0.5"    ) );

    // blank space:
    assert( 0.5 == string_to_double( "0.5 "   ) );
    assert( 0.5 == string_to_double( " 0.5"   ) );

    // trailing non digit characters:
    assert( 0.5 == string_to_double( "0.5a"   ) );

    // note that with your requirements you can't distinguish
    // all the the allowed string representation of zero from
    // the non numerical strings:
    assert( 0 == string_to_double( "0"       ) );
    assert( 0 == string_to_double( "0."      ) );
    assert( 0 == string_to_double( "0.0"     ) );
    assert( 0 == string_to_double( "0.00"    ) );
    assert( 0 == string_to_double( "0.0e0"   ) );
    assert( 0 == string_to_double( "0.0e-0"  ) );
    assert( 0 == string_to_double( "0.0e+0"  ) );
    assert( 0 == string_to_double( "+0"      ) );
    assert( 0 == string_to_double( "+0."     ) );
    assert( 0 == string_to_double( "+0.0"    ) );
    assert( 0 == string_to_double( "+0.00"   ) );
    assert( 0 == string_to_double( "+0.0e0"  ) );
    assert( 0 == string_to_double( "+0.0e-0" ) );
    assert( 0 == string_to_double( "+0.0e+0" ) );
    assert( 0 == string_to_double( "-0"      ) );
    assert( 0 == string_to_double( "-0."     ) );
    assert( 0 == string_to_double( "-0.0"    ) );
    assert( 0 == string_to_double( "-0.00"   ) );
    assert( 0 == string_to_double( "-0.0e0"  ) );
    assert( 0 == string_to_double( "-0.0e-0" ) );
    assert( 0 == string_to_double( "-0.0e+0" ) );
    assert( 0 == string_to_double( "foobar"  ) );
    return 0;
 }
Sign up to request clarification or add additional context in comments.

Comments

35

Most simple way is to use boost::lexical_cast:

double value;
try
{
    value = boost::lexical_cast<double>(my_string);
}
catch (boost::bad_lexical_cast const&)
{
    value = 0;
}

3 Comments

Exception handling should not be used for flow control. Exceptions are for exceptional conditions.
@adam, in this case boost::lexical_cast() throws when non-numeric data exists in my_string. As long as my_string most usually contains a number, then I'd say this fits the bill as an exceptional condition.
Unfortunately this will look like it works for "10.5xxxx". Should this string also fail? or should it return 10.5?
21

atof and strtod do what you want but are very forgiving. If you don't want to accept strings like "32asd" as valid you need to wrap strtod in a function such as this:

#include <stdlib.h>
double strict_str2double(char* str)
{
    char* endptr;
    double value = strtod(str, &endptr);
    if (*endptr) return 0;
    return value;
}

2 Comments

note the empty string will be accepted by that code :) (endptr == str || *endptr) should fix it
If the string is empty, value will be 0.
7

If it is a c-string (null-terminated array of type char), you can do something like:

#include <stdlib.h>
char str[] = "3.14159";
double num = atof(str);

If it is a C++ string, just use the c_str() method:

double num = atof( cppstr.c_str() );

atof() will convert the string to a double, returning 0 on failure. The function is documented here: http://www.cplusplus.com/reference/clibrary/cstdlib/atof.html

Comments

5
#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout << stod("  99.999  ") << endl;
}

Output: 99.999 (which is double, whitespace was automatically stripped)

Since C++11 converting string to floating-point values (like double) is available with functions:
stof - convert str to a float
stod - convert str to a double
stold - convert str to a long double

I want a function that returns 0 when the string is not numerical.

You can add try catch statement when stod throws an exception.

Comments

3

Must say I agree with that the most elegant solution to this is using boost::lexical_cast. You can then catch the bad_lexical_cast that might occure, and do something when it fails, instead of getting 0.0 which atof gives.

#include <boost/lexical_cast.hpp>
#include <string>

int main()
{
    std::string str = "3.14";
    double strVal;
    try {
        strVal = boost::lexical_cast<double>(str);
    } catch(bad_lexical_cast&) {
        //Do your errormagic
    }
    return 0;
}

Comments

1

One of the most elegant solution to this problem is to use boost::lexical_cast as @Evgeny Lazin mentioned.

Comments

0

I think atof is exactly what you want. This function parses a string and converts it into a double. If the string does not start with a number (non-numerical) a 0.0 is returned.

However, it does try to parse as much of the string as it can. In other words, the string "3abc" would be interpreted as 3.0. If you want a function that will return 0.0 in these cases, you will need to write a small wrapper yourself.

Also, this function works with the C-style string of a null terminated array of characters. If you're using a string object, it will need to be converted to a char* before you use this function.

Comments

0

There is not a single function that will do that, because 0 is a valid number and you need to be able to catch when the string is not a valid number.

You will need to check the string first (probably with a regular expression) to see if it contains only numbers and numerical punctuation. You can then decide to return 0 if that is what your application needs or convert it to a double.

After looking up atof() and strtod() I should rephrase my statement to "there shouldn't be" instead of "there is not" ... hehe

Comments

0

Sample C program to convert string to double in C

#include <iostream>
#include <comutil.h>
#include <iomanip>

bool ParseNumberToDouble(const std::wstring& strInput, double & dResult)
{
    bool bSucceeded = false;
    dResult = 0;
    if (!strInput.empty() && dResult)
    {
        _variant_t varIn = strInput.c_str();
        if (SUCCEEDED(VariantChangeTypeEx(&varIn, &varIn, GetThreadLocale(), 0, VT_R8)))
        {
            dResult = varIn.dblVal;
            bSucceeded = true;
        }
    }
    return bSucceeded;
}

int main()
{
    std::wstring strInput = L"1000";
    double dResult = 0;

    ParseNumberToDouble(strInput, dResult);

    return 0;
}

Comments