Convert String to float in c++
I want to convert a std::string
which I read from a csv file 开发者_Go百科to a float
. There are several float representations included like:
0,0728239
6.543.584.399
2,67E-02
These string should all be floats. First I used atof()
, but the conversion was wrong:
2,67E-02 -> 2
6.543.584.399 -> 6.543
Then I used boost::lexical_cast<float>()
, but when it comes to a float with an exponent included, it throws following exception
`terminate` called after throwing an instance of
`'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_lexical_cast> >'`
`what()`: bad lexical cast: source type value could not be interpreted as target
Aborted
What is the best way to get all three types of strings converted to a float?
scanf
with the correct locale set. Seriously. Save yourself the hassle of doing it the "c++ way" in this case.
http://www.cplusplus.com/reference/clibrary/clocale/
Notice that locale configuration affects the behavior of many functions within the standard C library: In string.h, functions strcoll and strxfrm are affected by character transformation rules. In ctype.h, all functions except for isdigit and isxdigit are affected by the extended character set selected. In stdio.h, formatted input/output operations are affected by character transformation rules and decimal-point character set in the numeric formatting settings. In time.h, the function strftime is affected by the time formatting settings. In this header, it affects the value returned by its functions setlocale and localeconv.
http://www.cplusplus.com/reference/clibrary/clocale/setlocale/
setlocale ( LC_NUMERIC, "" ); // "" is the Environment's default locale
Then you can use atof, scanf, etc correctly. However, that's the C way of doing things. The C++ way is:
float stof(const std::string& input) {
std::stringstream ss;
float result;
static std::locale uselocale("") //again, "" is Environment's default locale
ss.imbue(uselocale);
ss << input;
ss >> result;
return result;
}
All compilers must accept these locales: "", "C"
MSVC accepts these locales: http://msdn.microsoft.com/en-us/library/hzz3tw78.aspx
(wait, does MSVC setlocale
really not accept "en_US"?)
GCC accepts these locales: http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html#locale.impl.c
This should do :
#include <sstream>
#include <iostream>
#include <algorithm>
bool isdot(const char &c)
{
return '.'==c;
}
float to(std::string s)
{
s.erase(std::remove_if(s.begin(), s.end(), &isdot ),s.end());
replace(s.begin(), s.end(), ',', '.');
std::stringstream ss(s);
float v = 0;
ss >> v;
return v;
}
int main()
{
const std::string a1("0,0728239");
const std::string a2("6.543.584.399");
const std::string a3("2,67E-02");
std::cout << to(a1)<<std::endl;
std::cout << to(a2)<<std::endl;
std::cout << to(a3)<<std::endl;
}
See it live on coliru
精彩评论