Как я могу преобразовать строку в double в C ++? - PullRequest
34 голосов
/ 25 декабря 2008

Как я могу преобразовать строку в double в C ++? Мне нужна функция, которая возвращает 0, когда строка не числовая.

Ответы [ 9 ]

38 голосов
/ 25 декабря 2008

См. C ++ FAQ Lite Как мне преобразовать std :: string в число?

См. C ++ Super-FAQ Как мне преобразовать std :: string в число?

Обратите внимание, что с вашими требованиями вы не можете отличить все допустимые строковые представления нуля от нечисловых строк.

 // the requested function
 #include <sstream>
 double string_to_double( const std::string& s )
 {
   std::istringstream i(s);
   double x;
   if (!(i >> x))
     return 0;
   return x;
 } 

 // some tests
 #include <cassert>
 int main( int, char** )
 {
    // simple case:
    assert( 0.5 == string_to_double( "0.5"    ) );

    // blank space:
    assert( 0.5 == string_to_double( "0.5 "   ) );
    assert( 0.5 == string_to_double( " 0.5"   ) );

    // trailing non digit characters:
    assert( 0.5 == string_to_double( "0.5a"   ) );

    // note that with your requirements you can't distinguish
    // all the the allowed string representation of zero from
    // the non numerical strings:
    assert( 0 == string_to_double( "0"       ) );
    assert( 0 == string_to_double( "0."      ) );
    assert( 0 == string_to_double( "0.0"     ) );
    assert( 0 == string_to_double( "0.00"    ) );
    assert( 0 == string_to_double( "0.0e0"   ) );
    assert( 0 == string_to_double( "0.0e-0"  ) );
    assert( 0 == string_to_double( "0.0e+0"  ) );
    assert( 0 == string_to_double( "+0"      ) );
    assert( 0 == string_to_double( "+0."     ) );
    assert( 0 == string_to_double( "+0.0"    ) );
    assert( 0 == string_to_double( "+0.00"   ) );
    assert( 0 == string_to_double( "+0.0e0"  ) );
    assert( 0 == string_to_double( "+0.0e-0" ) );
    assert( 0 == string_to_double( "+0.0e+0" ) );
    assert( 0 == string_to_double( "-0"      ) );
    assert( 0 == string_to_double( "-0."     ) );
    assert( 0 == string_to_double( "-0.0"    ) );
    assert( 0 == string_to_double( "-0.00"   ) );
    assert( 0 == string_to_double( "-0.0e0"  ) );
    assert( 0 == string_to_double( "-0.0e-0" ) );
    assert( 0 == string_to_double( "-0.0e+0" ) );
    assert( 0 == string_to_double( "foobar"  ) );
    return 0;
 }
35 голосов
/ 25 декабря 2008

Самый простой способ - использовать boost :: lexical_cast :

double value;
try
{
    value = boost::lexical_cast<double>(my_string);
}
catch (boost::bad_lexical_cast const&)
{
    value = 0;
}
20 голосов
/ 25 декабря 2008

atof и strtod делают то, что вы хотите, но очень снисходительны. Если вы не хотите принимать строки типа «32asd» как действительные, вам нужно заключить strtod в такую ​​функцию, как эта:

#include <stdlib.h>
double strict_str2double(char* str)
{
    char* endptr;
    double value = strtod(str, &endptr);
    if (*endptr) return 0;
    return value;
}
7 голосов
/ 25 декабря 2008

Если это c-строка (массив с нулевым символом в конце типа char), вы можете сделать что-то вроде:

#include <stdlib.h>
char str[] = "3.14159";
double num = atof(str);

Если это строка C ++, просто используйте метод c_str ():

double num = atof( cppstr.c_str() );

atof () преобразует строку в двойную, возвращая 0 при ошибке. Функция задокументирована здесь: http://www.cplusplus.com/reference/clibrary/cstdlib/atof.html

5 голосов
/ 12 июня 2015
#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout << stod("  99.999  ") << endl;
}

Вывод: 99.999 (что вдвое больше, пробел был автоматически удален)

Поскольку в C ++ 11 преобразование строки в значения с плавающей точкой (например, double) доступно с функциями:
stof - преобразовать str в число с плавающей точкой
Stod - преобразовать str в двойной
stold - преобразовать str в длинный двойной

Мне нужна функция, которая возвращает 0, если строка не числовая.

Вы можете добавить оператор try catch, когда stod выдает исключение.

3 голосов
/ 25 декабря 2008

Должен сказать, что я согласен с тем, что наиболее элегантным решением для этого является использование boost :: lexical_cast. Затем вы можете перехватить bad_lexical_cast, который может произойти, и сделать что-нибудь, если это не удастся, вместо получения 0.0, которое дает atof.

#include <boost/lexical_cast.hpp>
#include <string>

int main()
{
    std::string str = "3.14";
    double strVal;
    try {
        strVal = boost::lexical_cast<double>(str);
    } catch(bad_lexical_cast&) {
        //Do your errormagic
    }
    return 0;
}
1 голос
/ 25 декабря 2008

Одним из наиболее элегантных решений этой проблемы является использование boost :: lexical_cast, как упоминал @Evgeny Lazin.

0 голосов
/ 25 декабря 2008

Нет ни одной функции, которая будет это делать, потому что 0 - это допустимое число, и вам нужно иметь возможность перехватывать, когда строка не является допустимым числом.

Сначала вам нужно проверить строку (возможно, с помощью регулярного выражения), чтобы увидеть, содержит ли она только цифры и знаки препинания. Затем вы можете решить вернуть 0, если это то, что нужно вашему приложению, или преобразовать его в double.

После поиска atof () и strtod () Я должен перефразировать свое утверждение как "не должно быть" вместо "нет" ... хе-хе

0 голосов
/ 25 декабря 2008

Я думаю atof это именно то, что вы хотите. Эта функция анализирует строку и преобразует ее в двойную. Если строка не начинается с числа (не числового), возвращается 0.0.

Однако он пытается проанализировать как можно больше строки. Другими словами, строка «3abc» будет интерпретирована как 3.0. Если вам нужна функция, которая в этих случаях будет возвращать 0.0, вам нужно будет написать небольшую оболочку самостоятельно.

Кроме того, эта функция работает со строкой в ​​стиле C массива символов с нулевым символом в конце. Если вы используете строковый объект, его необходимо преобразовать в символ *, прежде чем использовать эту функцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...