One major "problem" with the C++11 string conversion functions is they throw an exception when they are unable to convert from a string. C++17 introduced a non-throwing function: std::from_chars. https://en.cppreference.com/w/cpp/utility/from_chars
The newer conversion function is for C strings and is numeric type neutral, you call the same function whether you want an integer or floating point value, the return variable type parameter determines the type returned.
FYI, if you are going to include a link do NOT put parentheses around it; or put a space at the before the closing parenthesis. Without the space the closing parenthesis is assumed to be part of the link, creating a 404.
Here's an example using stod like FurryGuy mentioned. It uses try-catch to filter out bad parses, which is generally frowned upon, but the standard library didn't give us something better until C++17 (edit: Actually, the >> extraction from a stringstream can also be used, I forgot about that)
Another way to convert a C++ string to a number is using a std::stringstream and extract to the desired numeric type. If no number is extracted zero is written to the variable and the failbit is set. https://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt
@Ganado, when including links I either put them on separate lines, or put spaces around the link(s). Your method is one I hadn't thought of. Thanks for the nice alternative.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
usingnamespace std;
vector<double> getNumbers( string str )
{
vector<double> numbers;
for ( int p = 0; !str.empty() && p < str.size(); p++ )
{
p = str.find_first_of( "0123456789-.", p );
if ( p == string::npos ) break;
stringstream ss( str.substr( p ) );
double x;
if ( ss >> x )
{
numbers.push_back( x );
if ( !getline( ss, str ) ) break;
p = 0;
}
}
return numbers;
}
int main()
{
string str;
//cout << "Enter a string to evaluate: ";
//getline( cin, str );
str = "The total price for 3 apples with 0 defect is $3.20 after 21% discount, which saved $0.8";
vector<double> numbers = getNumbers( str );
for ( auto e : numbers ) cout << e << " ";
}
Hi Ganado, your example works fine but when there is no space in front or behind the number, it could unable to get the same result.
Let's say the string changed to this, it cant get the number, 0. The total price for 3 apples with defect=0 is $3.20 after 21% discount, which saved $0.8.
But if the string changed to this, it can get the number, 0. The total price for 3 apples with defect= 0 is $3.20 after 21% discount, which saved $0.8.
Hi lastchance, appreciate your example but I get error on line 33 because it is a range-based for loop. Sorry that I forgot to mention I'm using C++98.
syntax error : missing ',' before ':'
missing type specifier - int assumed. Note: C++ does not support default-int
Any reference for this line to convert it to able to be run on C++98?
@Joshua0101,
I think that C++11 was such a major advance on the first standardised version that it really would be a better idea to upgrade your compiler. However, to avoid range-based loops (and auto):
for ( int e = 0; e < numbers.size(); e++ ) cout << numbers[e] << " ";
The alternative, with iterators, is even longer.
#include <iostream>
#include <sstream>
int main()
{
std::string str{"3; 0; 3.20; 21; 0.8"};
std::stringstream iss;
iss << str;
int a{};
int b{};
double c{};
int d{};
double e{};
char dummy;
iss >> a >> dummy >> b >> dummy >> c >> dummy >> d >> dummy >> e;
double sum = a + b + c + d + e;
std::cout << a << ' ' << b << ' ' << c << ' ' << d << ' ' << e << '\n';
std::cout << sum << '\n';
return 0;
}