I'm trying to convert std::string to float/double.
I tried:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
But it always returns zero. Any other ways?
I'm trying to convert std::string to float/double.
I tried:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
But it always returns zero. Any other ways?
std::string num = "0.6";
double temp = ::atof(num.c_str());
Does it for me, it is a valid C++ syntax to convert a string to a double.
You can do it with the stringstream or boost::lexical_cast but those come with a performance penalty.
Ahaha you have a Qt project ...
QString winOpacity("0.6");
double temp = winOpacity.toDouble();
Extra note:
If the input data is a const char*, QByteArray::toDouble will be faster.
Lexical cast is very nice.
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
using std::endl;
using std::cout;
using std::string;
using boost::lexical_cast;
int main() {
string str = "0.6";
double dub = lexical_cast<double>(str);
cout << dub << endl;
}
You can use std::stringstream:
#include <sstream>
#include <string>
template<typename T>
T StringToNumber(const std::string& numberAsString)
{
T valor;
std::stringstream stream(numberAsString);
stream >> valor;
if (stream.fail()) {
std::runtime_error e(numberAsString);
throw e;
}
return valor;
}
Usage:
double number= StringToNumber<double>("0.6");
Yes, with a lexical cast. Use a stringstream and the << operator, or use Boost, they've already implemented it.
Your own version could look like:
template<typename to, typename from>to lexical_cast(from const &x) {
std::stringstream os;
to ret;
os << x;
os >> ret;
return ret;
}
You can use boost lexical cast:
#include <boost/lexical_cast.hpp>
string v("0.6");
double dd = boost::lexical_cast<double>(v);
cout << dd << endl;
Note: boost::lexical_cast throws exception so you should be prepared to deal with it when you pass invalid value, try passing string("xxx")
If you don't want to drag in all of boost, go with strtod(3) from <cstdlib> - it already returns a double.
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;
int main() {
std::string num = "0.6";
double temp = ::strtod(num.c_str(), 0);
cout << num << " " << temp << endl;
return 0;
}
Outputs:
$ g++ -o s s.cc
$ ./s
0.6 0.6
$
Why atof() doesn't work ... what platform/compiler are you on?
With C++17, you can use std::from_chars, which is a lighter weight faster alternative to std::stof and std::stod. It doesn't involve any memory allocation or look at the locale, and it is non-throwing.
The std::from_chars function returns a value of type from_chars_result, which is basically a struct with two fields:
struct from_chars_result {
const char* ptr;
std::errc ec;
};
By inspecting ec we can tell if the conversion was successful:
#include <iostream>
#include <charconv>
int main()
{
const std::string str { "12345678901234.123456" };
double value = 0.0;
auto [p, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
if (ec != std::errc()) {
std::cout << "Couldn't convert value";
}
return 0;
}
NB: you need a fairly up-to-date compiler (e.g. gcc11) for std::from_chars to work with floating point types.
double myAtof ( string &num){
double tmp;
sscanf ( num.c_str(), "%lf" , &tmp);
return tmp;
}
This answer is backing up litb in your comments. I have profound suspicions you are just not displaying the result properly.
I had the exact same thing happen to me once. I spent a whole day trying to figure out why I was getting a bad value into a 64-bit int, only to discover that printf was ignoring the second byte. You can't just pass a 64-bit value into printf like its an int.
As to why atof() isn't working in the original question: the fact that it's cast to double makes me suspicious. The code shouldn't compile without #include <stdlib.h>, but if the cast was added to solve a compile warning, then atof() is not correctly declared. If the compiler assumes atof() returns an int, casting it will solve the conversion warning, but it will not cause the return value to be recognized as a double.
#include <stdlib.h>
#include <string>
...
std::string num = "0.6";
double temp = atof(num.c_str());
should work without warnings.
Rather than dragging Boost into the equation, you could keep your string (temporarily) as a char[] and use sprintf().
But of course if you're using Boost anyway, it's really not too much of an issue.