How can I convert string to double in C++? I want a function that returns 0 when the string is not numerical.
- 
                    You should give this a more descriptive title or no one will help. – dancavallaro Dec 25 '08 at 17:18
- 
                    What about a string that contains a double with extra junk on the end? – Martin York Dec 27 '08 at 07:08
- 
                    15How about some of the examples from the following: http://www.codeproject.com/KB/recipes/Tokenizer.aspx They are very efficient and somewhat elegant. – Nov 06 '10 at 06:29
- 
                    See answers to similar question [How to parse a string to an int in C++?](http://stackoverflow.com/questions/194465/how-to-parse-a-string-to-an-int-in-c) – Eugene Yokota Dec 25 '08 at 17:34
- 
                    2Why return 0 when you could return NaN? – Inverse Nov 17 '13 at 00:56
- 
                    possible duplicate of [How do I convert a double into a string in C++?](http://stackoverflow.com/questions/332111/how-do-i-convert-a-double-into-a-string-in-c) – jb. May 22 '14 at 16:21
- 
                    1Not a duplicate, this is the opposite operation. – JasonMArcher May 22 '14 at 17:33
10 Answers
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;
 }
 
    
    - 18,047
- 15
- 98
- 153
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;
}
 
    
    - 7,289
- 6
- 48
- 62
 
    
    - 9,193
- 6
- 47
- 83
- 
                    2Exception handling should not be used for flow control. Exceptions are for _exceptional_ conditions. – Adam Rosenfield Dec 25 '08 at 17:48
- 
                    4@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. – oz10 Dec 26 '08 at 03:20
- 
                    2Unfortunately this will look like it works for "10.5xxxx". Should this string also fail? or should it return 10.5? – Martin York Dec 27 '08 at 07:03
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;
}
 
    
    - 18,754
- 7
- 41
- 61
- 
                    2note the empty string will be accepted by that code :) (endptr == str || *endptr) should fix it – Johannes Schaub - litb Dec 25 '08 at 23:01
- 
                    1
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
 
    
    - 6,435
- 4
- 34
- 45
#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.
 
    
    - 4,967
- 4
- 34
- 50
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;
}
 
    
    - 1,636
- 2
- 18
- 23
One of the most elegant solution to this problem is to use boost::lexical_cast as @Evgeny Lazin mentioned.
 
    
    - 8,273
- 12
- 61
- 97
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.
 
    
    - 77,653
- 43
- 148
- 164
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
 
    
    - 10,923
- 4
- 26
- 35
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;
}
 
    
    - 31
- 1
- 8
