Конвертировать String для плавания в C ++ - PullRequest
0 голосов
/ 05 октября 2011

Я хочу преобразовать std::string, который я прочитал из файла CSV, в float. Есть несколько представлений с плавающей точкой, таких как:

0,0728239
6.543.584.399
2,67E-02

Эти строки должны быть плавающими. Сначала я использовал atof(), но преобразование было неверным:

2,67E-02 -> 2
6.543.584.399 -> 6.543

Затем я использовал boost::lexical_cast<float>(), но когда дело доходит до числа с плавающей запятой, он выдает следующее исключение

`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

Как лучше всего преобразовать все три типа строк в число с плавающей точкой?

Ответы [ 3 ]

6 голосов
/ 05 октября 2011

scanf с правильной настройкой локали.Шутки в сторону.В этом случае избавьте себя от хлопот, связанных с "путём c ++".

5 голосов
/ 05 октября 2011

http://www.cplusplus.com/reference/clibrary/clocale/

Обратите внимание, что конфигурация локали влияет на поведение многих функции в стандартной библиотеке C: в string.h, На функции strcoll и strxfrm влияет преобразование символов правила. В ctype.h все функции, кроме isdigit и На isxdigit влияет выбранный расширенный набор символов. В stdio.h, отформатированные операции ввода / вывода затрагиваются по правилам преобразования символов и десятичной запятой в настройки числового форматирования. В time.h, функция На strftime влияют настройки форматирования времени. В этом заголовке это влияет на значение, возвращаемое его функциями setlocale и localeconv.

http://www.cplusplus.com/reference/clibrary/clocale/setlocale/

setlocale ( LC_NUMERIC, "" ); // "" is the Environment's default locale

Тогда вы можете правильно использовать atof, scanf и т. Д. Тем не менее, это способ C делать вещи. C ++ путь:

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;
}

Все компиляторы должны принимать следующие локали: "", "C"
MSVC принимает следующие локали: http://msdn.microsoft.com/en-us/library/hzz3tw78.aspx
(подождите, MSVC setlocale действительно не принимает "en_US"?)
GCC принимает следующие локали: http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html#locale.impl.c

0 голосов
/ 05 октября 2011

Это должно сделать:

#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;
}

Посмотреть это жить на колиру

...