Как преобразовать число в строку и наоборот в C ++ - PullRequest
118 голосов
/ 13 марта 2011

Поскольку этот вопрос задают каждую неделю, этот FAQ может помочь многим пользователям.

  • Как преобразовать целое число в строку в C ++

  • как преобразовать строку в целое число в C ++

  • как преобразовать число с плавающей запятой в строку в C ++

  • как преобразовать строку в число с плавающей запятой в C ++

Ответы [ 4 ]

124 голосов
/ 18 июня 2012

Обновление для C ++ 11

Начиная со стандарта C++11, преобразование строки в число и наоборот встроено в стандартную библиотеку. Все следующие функции присутствуют в <string> (согласно параграфу 21.5).

строка в числовое значение

float              stof(const string& str, size_t *idx = 0);
double             stod(const string& str, size_t *idx = 0);
long double        stold(const string& str, size_t *idx = 0);
int                stoi(const string& str, size_t *idx = 0, int base = 10);
long               stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long      stoul(const string& str, size_t *idx = 0, int base = 10);
long long          stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);

Каждый из них принимает строку в качестве ввода и пытается преобразовать ее в число. Если действительное число не может быть построено, например, из-за отсутствия числовых данных или числа, выходящего за пределы допустимого для типа, генерируется исключение (std::invalid_argument или std::out_of_range).

Если преобразование выполнено успешно и idx не равно 0, idx будет содержать индекс первого символа, который не использовался для декодирования. Это может быть индекс позади последнего символа.

Наконец, целочисленные типы позволяют указать базу, для цифр больше 9 предполагается алфавит (от a=10 до z=35). Вы можете найти больше информации о точном форматировании, которое может быть проанализировано здесь для чисел с плавающей запятой , целых чисел со знаком и целых чисел без знака .

Наконец, для каждой функции есть также перегрузка, которая принимает std::wstring в качестве первого параметра.

цифра в строку

string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);

Это более просто: вы передаете соответствующий числовой тип и получаете строку назад. Для параметров форматирования вы должны вернуться к опции C ++ 03 stringsream и использовать потоковые манипуляторы, как объяснено в другом ответе здесь.

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

Существуют также аналогичные определенные функции с именем to_wstring, которые будут возвращать std::wstring.

84 голосов
/ 13 марта 2011

Как преобразовать число в строку в C ++ 03

  1. Не используйте функции itoa или itof, потому чтоони нестандартны и поэтому не переносимы.
  2. Использовать строковые потоки

     #include <sstream>  //include this to use string streams
     #include <string> 
    
    int main()
    {    
        int number = 1234;
    
        std::ostringstream ostr; //output string stream
        ostr << number; //use the string stream just like cout,
        //except the stream prints not to stdout but to a string.
    
        std::string theNumberString = ostr.str(); //the str() function of the stream 
        //returns the string.
    
        //now  theNumberString is "1234"  
    }
    

    Обратите внимание, что строковые потоки можно использовать и для преобразования с плавающей запятойчисла в строку, а также для форматирования строки, как вы хотите, как и с cout

    std::ostringstream ostr;
    float f = 1.2;
    int i = 3;
    ostr << f << " + " i << " = " << f + i;   
    std::string s = ostr.str();
    //now s is "1.2 + 3 = 4.2" 
    

    Вы можете использовать потоковые манипуляторы, такие как std::endl, std::hex и функции std::setw(),std::setprecision() и т. Д. Со строковыми потоками точно так же, как с cout

    Не путайте std::ostringstream с std::ostrstream.Последний не рекомендуется

  3. Использовать повысить лексическое приведение .Если вы не знакомы с boost, лучше начать с небольшой библиотеки, такой как lexical_cast.Чтобы загрузить и установить boost и его документацию , перейдите сюда .Хотя boost не соответствует стандарту C ++, многие библиотеки boost в конечном итоге стандартизируются, и boost считается одной из лучших библиотек C ++.

    Лексическое приведение использует потоки внизу, поэтому в основном этот параметр такой же, как и предыдущий, только менее подробный.

    #include <boost/lexical_cast.hpp>
    #include <string>
    
    int main()
    {
       float f = 1.2;
       int i = 42;
       std::string sf = boost::lexical_cast<std::string>(f); //sf is "1.2"
       std::string si = boost::lexical_cast<std::string>(i); //sf is "42"
    }
    

Как преобразовать строку вчисло в C ++ 03

  1. Наиболее легким вариантом, унаследованным от C, являются функции atoi (для целых чисел (от алфавита до целого)) и atof (для плавающихзначения точек (в алфавитном порядке до числа с плавающей точкой)).Эти функции принимают в качестве аргумента строку в стиле C (const char *), и поэтому их использование может считаться не совсем хорошей практикой C ++.cplusplus.com имеет простую для понимания документацию по atoi и atof , включая их поведение в случае неправильного ввода.Однако ссылка содержит ошибку в том, что в соответствии со стандартом, если число ввода слишком велико, чтобы соответствовать целевому типу, поведение не определено.

    #include <cstdlib> //the standard C library header
    #include <string>
    int main()
    {
        std::string si = "12";
        std::string sf = "1.2";
        int i = atoi(si.c_str()); //the c_str() function "converts" 
        double f = atof(sf.c_str()); //std::string to const char*
    }
    
  2. Использовать строковые потоки (на этот раз входной поток строк, istringstream).Опять же, istringstream используется так же, как cin.Опять же, не путайте istringstream с istrstream.Последний не рекомендуется.

    #include <sstream>
    #include <string>
    int main()
    {
       std::string inputString = "1234 12.3 44";
       std::istringstream istr(inputString);
       int i1, i2;
       float f;
       istr >> i1 >> f >> i2;
       //i1 is 1234, f is 12.3, i2 is 44  
    }
    
  3. Использовать лексическое усиление .

    #include <boost/lexical_cast.hpp>
    #include <string>
    
    int main()
    {
       std::string sf = "42.2"; 
       std::string si = "42";
       float f = boost::lexical_cast<float>(sf); //f is 42.2
       int i = boost::lexical_cast<int>(si);  //i is 42
    }       
    

    В случае неправильного ввода, lexical_castвыдает исключение типа boost::bad_lexical_cast

2 голосов
/ 18 мая 2018

В C ++ 17 новые функции std :: to_chars и std :: from_chars введены в заголовок charconv .

std :: to_chars не зависит от локали, не выделяется, и не бросать.

Только небольшое подмножество политик форматирования, используемых другие библиотеки (такие как std :: sprintf) предоставляются.

From std :: to_chars , то же самое для std :: from_chars .

Гарантия того, что std :: from_chars может восстановиться каждое значение с плавающей точкой отформатировано to_chars точно предоставляется только если оба функции из той же реализации

 // See en.cppreference.com for more information, including format control.
#include <cstdio>
#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <charconv>

using Type =  /* Any fundamental type */ ;
std::size_t buffer_size = /* ... */ ;

[[noreturn]] void report_and_exit(int ret, const char *output) noexcept 
{
    std::printf("%s\n", output);
    std::exit(ret);
}
void check(const std::errc &ec) noexcept
{
    if (ec ==  std::errc::value_too_large)
        report_and_exit(1, "Failed");
}
int main() {
    char buffer[buffer_size];        
    Type val_to_be_converted, result_of_converted_back;

    auto result1 = std::to_chars(buffer, buffer + buffer_size,  val_to_be_converted);
    check(result1.ec);
    *result1.ptr = '\0';

    auto result2 = std::from_chars(buffer, result1.ptr, result_of_converted_back);
    check(result2.ec);

    assert(val_to_be_converted == result_of_converted_back);
    report_and_exit(0, buffer);
}

Хотя это не полностью реализовано компиляторами, оно определенно будет реализовано.

0 голосов
/ 13 марта 2011

Я украл этот удобный класс где-то здесь, в StackOverflow, чтобы преобразовать что-либо пригодное для преобразования в строку:

// make_string
class make_string {
public:
  template <typename T>
  make_string& operator<<( T const & val ) {
    buffer_ << val;
    return *this;
  }
  operator std::string() const {
    return buffer_.str();
  }
private:
  std::ostringstream buffer_;
};

И затем вы используете его как;

string str = make_string() << 6 << 8 << "hello";

Довольно изящно!

Также я использую эту функцию для преобразования строк во что-либо растекаемое, хотя это не очень безопасно, если вы пытаетесь проанализировать строку, не содержащую число; (и не так умно, как предыдущий)

// parse_string
template <typename RETURN_TYPE, typename STRING_TYPE>
RETURN_TYPE parse_string(const STRING_TYPE& str) {
  std::stringstream buf;
  buf << str;
  RETURN_TYPE val;
  buf >> val;
  return val;
}

Использовать как:

int x = parse_string<int>("78");

Возможно, вам также понадобятся версии для строк wstring.

...