开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜