Самый простой способ конвертировать int в строку в C ++

1285

Самый простой способ конвертировать из int в эквивалентную string в C++. Я знаю два метода. Есть ли более простой способ?

(1)

int a = 10;
char *intStr = itoa(a);
string str = string(intStr);

(2)

int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
  • 3
    Я думаю, что оба метода вы дали хорошие решения. это зависит от контекста, где вам нужно это сделать. Если вы уже работаете с потоками, например, читаете или пишете файл, тогда ваш второй метод - лучший. Если вам нужно передать int как строку в аргумент функции, тогда itoa может быть простым способом. Но в большинстве случаев при работе с файлами происходит преобразование int в строку, поэтому потоки являются подходящими.
  • 39
    Как вариант 1 вообще работает для вас? itoa() я понимаю, itoa() принимает три параметра.
Показать ещё 3 комментария
Теги:
string
type-conversion
int

25 ответов

1615
Лучший ответ

С++ 11 вводит std::stoi (и варианты для каждого числового типа) и std::to_string, аналоги C atoi и itoa но выражается в std::to_string std::string.

#include <string> 

std::string s = std::to_string(42);

поэтому самый короткий способ, о котором я могу думать. Вы даже можете опустить именование типа, используя ключевое слово auto:

auto s = std::to_string(42);

Примечание: см. [String.conversions] (21.5 в n3242)

  • 190
    to_string не является членом std fix: stackoverflow.com/questions/12975341/…
  • 30
    Или, в зависимости от вашего компилятора, просто установите правильный языковой стандарт: g++ -std=c++11 someFile.cc
Показать ещё 15 комментариев
163

Подводя обсуждение с помощью @v.oddou пару лет спустя, C++ 17 наконец-то предоставил способ сделать изначально макро-основанное на тип-агностическое решение (сохранившееся ниже), не пройдя макроуглеродность.

// variadic template
template < typename... Args >
std::string sstr( Args &&... args )
{
    std::ostringstream sstr;
    // fold expression
    ( sstr << std::dec << ... << args );
    return sstr.str();
}

Использование:

int i = 42;
std::string s = sstr( "i is: ", i );
puts( sstr( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( sstr( "Foo is '", x, "', i is ", i ) );

Оригинальный ответ:

Поскольку "преобразование... в строку" является повторяющейся проблемой, я всегда определяю макрос SSTR() в центральном заголовке моих C++ источников:

#include <sstream>

#define SSTR( x ) static_cast< std::ostringstream & >( \
        ( std::ostringstream() << std::dec << x ) ).str()

Использование настолько просто, насколько это возможно:

int i = 42;
std::string s = SSTR( "i is: " << i );
puts( SSTR( i ).c_str() );

Foo x( 42 );
throw std::runtime_error( SSTR( "Foo is '" << x << "', i is " << i ) );

Вышеупомянутый C++ 98 совместим (если вы не можете использовать C++ 11 std::to_string) и не нуждаетесь в каких-либо сторонних lexical_cast<> (если вы не можете использовать Boost lexical_cast<>); однако оба этих решения имеют лучшую производительность.

  • 2
    Я не очень знаком с dynamic_cast но я использую clang для компиляции, поэтому он жалуется на это. Если я просто опускаю dynamic_cast то он компилируется нормально; какой цели служит dynamic_cast в этом случае? Мы уже создаем ostringstream , так зачем его ostringstream ?
  • 2
    @ Mathew: ссылка в моем ответе приводит к подробному описанию каждой части конструкции. В то время как мы создали ostringstream , мы вызвали к нему operator<<() , который возвращает ostream & - для которого .str() не определен. Мне действительно интересно, как clang сделал бы эту работу без приведения (или почему он генерирует ошибку с ним). Эта конструкция публикуется во многих местах, и я уже более десяти лет использую ее на многих различных компиляторах, включая MSVC, GCC и XLC, поэтому я довольно удивлен, что ее не устраивает.
Показать ещё 7 комментариев
100

Обычно я использую следующий метод:

#include <sstream>

template <typename T>
  std::string NumberToString ( T Number )
  {
     std::ostringstream ss;
     ss << Number;
     return ss.str();
  }

подробно описан здесь.

  • 1
    Перед использованием ss вам необходимо выполнить ss.clear() . Я видел неожиданные результаты без этой инициализации.
  • 13
    @lifebalance: я никогда не видел такого поведения.
Показать ещё 4 комментария
84

Вероятно, наиболее распространенный простой способ, по сути, включает ваш второй выбор в шаблон с именем lexical_cast, например, в Boost, поэтому ваш код выглядит следующим образом:

int a = 10;
string s = lexical_cast<string>(a);

Одна из них заключается в том, что она поддерживает другие отливки (например, в противоположном направлении работает так же хорошо).

Также обратите внимание, что хотя Boost lexical_cast начинался как просто запись в строковый поток, а затем извлечение обратно из потока, теперь у него есть несколько дополнений. Прежде всего, были добавлены специализации для довольно многих типов, поэтому для многих распространенных типов они существенно быстрее, чем использование строкового потока. Во-вторых, теперь он проверяет результат, поэтому (например), если вы преобразовываете из строки в int, он может генерировать исключение, если строка содержит то, что не может быть преобразовано в int (например, 1234 будет успешным, но 123abc будет бросать).

Как и в С++ 11, существует функция std::to_string, перегруженная для целых типов, поэтому вы можете использовать код, например:

int a = 20;
std::string s = to_string(a);

Стандарт определяет их как эквивалент выполнения преобразования с помощью sprintf (используя спецификатор преобразования, который соответствует предоставленному типу объекта, например %d для int), в буфер достаточного размера, тогда создавая std::string содержимого этого буфера.

  • 2
    Хорошо, я предпочитаю ответ Кевина, хотя он показывает include и пространство имен. Просто незначительный захват. :) Хорошая работа, хотя!
  • 4
    Я бы сказал, что это путь, если у вас нет поддержки C ++ 11.
Показать ещё 1 комментарий
43

Если у вас установлен Boost (что вам нужно):

#include <boost/lexical_cast.hpp>

int num = 4;
std::string str = boost::lexical_cast<std::string>(num);
  • 4
    Договорились об установке буста. Я думаю, что более часто можно было бы отформатировать строку. Для этой цели я предпочитаю boost :: format например format ("% 02d", number) .str ()
28

Не было бы проще использовать строковые потоки?

#include <sstream>

int x=42;            //The integer
string str;          //The string
ostringstream temp;  //temp as in temporary
temp<<x;
str=temp.str();      //str is temp as string

Или выполните функцию:

#include <sstream>

string IntToString (int a)
{
    ostringstream temp;
    temp<<a;
    return temp.str();
}
19

Не то, что я знаю, в чистом С++. Но небольшая модификация того, что вы упомянули

string s = string(itoa(a));

должен работать, и он довольно короткий.

  • 50
    itoa() не является стандартной функцией!
  • 3
    @cartoonist: Тогда что это?
Показать ещё 1 комментарий
16

sprintf() довольно хорош для преобразования формата. Затем вы можете назначить полученную строку C строке С++, как вы это делали в 1.

  • 14
    и надеюсь, что используемый вами буфер достаточно велик ...
  • 1
    Хех да Тем не менее, я обычно полагаюсь на snprintf () и друзей во всем, что касается последствий при обработке C-строк.
Показать ещё 8 комментариев
12

Сначала включите:

#include <string>
#include <sstream>

Второе добавьте метод:

template <typename T>
string NumberToString(T pNumber)
{
 ostringstream oOStrStream;
 oOStrStream << pNumber;
 return oOStrStream.str();
}

Используйте метод следующим образом:

NumberToString(69);

или

int x = 69;
string vStr = NumberToString(x) + " Hello word!."
9

Вы можете использовать std::to_string доступные в C++ 11, как предложено Matthieu M.:

std::to_string(42);

Или, если производительность критическая (например, если вы делаете много конверсий), вы можете использовать fmt::FormatInt из библиотеки формата C++ для преобразования целого в std::string:

fmt::FormatInt(42).str();

Или строка C:

fmt::FormatInt f(42);
f.c_str();

Последний не выполняет динамических распределений памяти и более чем в 10 раз быстрее, чем std::to_string в тестах Boost Karma. Дополнительную информацию см. В разделе Быстрое целое число для преобразования строк в C++.

В отличие от std::to_string, fmt::FormatInt не требует C++ 11 и работает с любым компилятором C++.

Отказ от ответственности: я являюсь автором библиотеки формата C++.

  • 0
    Это потокобезопасно?
  • 0
    @ Сорен: Да, это потокобезопасный.
Показать ещё 3 комментария
8

Использование stringstream для преобразования чисел опасно!

См. Http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/, где указано, что operator<< вставляет форматированный вывод.

В зависимости от вашей текущей локали целое число, превышающее 3 цифры, можно преобразовать в строку из 4 цифр, добавив дополнительный разделитель тысяч.

Например, int = 1000 может быть преобразован в строку 1.001. Это может привести к тому, что операции сравнения не будут работать вообще.

Поэтому я настоятельно рекомендую использовать метод std::to_string. Это проще и делает то, что вы ожидаете.

  • 2
    Я согласен, что это серьезная проблема, если вам нужно обмениваться данными. К сожалению, также std::to_string использует текущую локаль (см. En.cppreference.com/w/cpp/string/basic_string/to_string , раздел «Заметки»). Почти все стандартные инструменты (от stringstream до sprintf , но также и sscanf т. Д.) Используют текущую локаль. Я не знал об этом до недавнего времени, когда это сильно ударило меня. В настоящее время используют домашние вещи, не трудно сделать.
  • 0
    В приведенной выше ссылке также указано, что C ++ 17 предоставляет std :: to_chars в качестве высокопроизводительной альтернативы, не зависящей от локали.
Показать ещё 1 комментарий
7

Для C++ 98 существует несколько вариантов:

boost/lexical_cast

Boost не является частью библиотеки C++, но содержит множество полезных расширений библиотеки.

lexical_cast функции lexical_cast предлагает удобную и согласованную форму для поддержки общих преобразований и от произвольных типов, когда они представлены в виде текста.
- Дополнительная документация

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

int main() {
    int x = 5;
    std::string x_str = boost::lexical_cast<std::string>(x);
    return 0;
}

Что касается времени выполнения, операция lexical_cast занимает около 80 микросекунд (на моей машине) при первом преобразовании, а затем значительно ускоряется после этого, если выполняется избыточно.


itoa

Эта функция не определена в ANSI-C и не является частью C++, но поддерживается некоторыми компиляторами.
- cplusplus.com

Это означает, что gcc/g++ не может скомпилировать код с помощью itoa.

#include <stdlib.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    x_str = itoa(x, x_str, 10); // base 10
    return 0;
}

Нет времени выполнения для отчета. У меня нет установленной Visual Studio, которая, как сообщается, может скомпилировать itoa.


sprintf

sprintf - это стандартная библиотечная функция C, которая работает на строках C, и является вполне допустимой альтернативой.

Составляет строку с тем же текстом, который будет напечатан, если формат был использован в printf, но вместо того, чтобы печатать, содержимое хранится как строка C в буфере, на который указывает str.
- cplusplus.com

#include <stdio.h>

int main() {
    int x = 5;
    char * x_str = new char[2];
    int chars_written = sprintf(x_str, "%d", x);
    return 0;
}

Заголовок stdio.h может не понадобиться. Что касается времени выполнения, операция sprintf занимает около 40 микросекунд (на моей машине) при первом преобразовании, а затем значительно ускоряется после этого, если выполняется избыточно.


stringstream

Это C++ библиотека основной способ преобразования целых чисел в строки, и наоборот. Существуют аналогичные функции сестры для stringstream которые дополнительно ограничивают предполагаемое использование потока, например, ostringstream. Использование ostringstream специально говорит читателю вашего кода, что вы только намерены использовать оператор <<, по существу. Эта функция - все, что особенно необходимо для преобразования целого числа в строку. См. Этот вопрос для более подробного обсуждения.

#include <sstream>
#include <string>

int main() {
    int x = 5;
    std::ostringstream stream;
    stream << x;
    std::string x_str = stream.str();
    return 0;
}

Что касается времени выполнения, операция ostringstream занимает около 71 микросекунды (на моей машине), а затем значительно ускоряется после этого, если выполняется избыточно, но не так сильно, как предыдущие функции.


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

  • 0
    Спасибо за заботу о нас (пользователи C ++ 98)
3

Довольно легко добавить синтаксический сахар, который позволяет составлять строки "на лету" потоковым способом

#include <string>
#include <sstream>

struct strmake {
    std::stringstream s;
    template <typename T> strmake& operator << (const T& x) {
        s << x; return *this;
    }   
    operator std::string() {return s.str();}
};

Теперь вы можете добавить все, что хотите (при условии, что для него определен оператор << (std::ostream&..)) в strmake() и использовать его вместо std::string.

Пример:

#include <iostream>

int main() {
    std::string x =
      strmake() << "Current time is " << 5+5 << ":" << 5*5 << " GST";
    std::cout << x << std::endl;
}
3

Использование:

#define convertToString(x) #x

int main()
{
    convertToString(42); // Returns const char* equivalent of 42
}
  • 1
    Работает только с литеральными числами, не оценивает переменное содержимое, хотя иногда полезно.
  • 0
    Правильно. Но определенно удобно во время
Показать ещё 1 комментарий
1
#include "stdafx.h"
#include<iostream>
#include<string>
#include<string.h>


std::string intToString(int num);

int main()
{

    int integer = 4782151;

    std::string integerAsStr = intToString(integer);

    std::cout << "integer = " << integer << std::endl;
    std::cout << "integerAsStr = " << integerAsStr << std::endl;


    return 0;
}

std::string intToString(int num)
{
    std::string numAsStr;

    while (num)
    {
        char toInsert = (num % 10) + 48;
        numAsStr.insert(0, 1, toInsert);

        num /= 10;
    }

    return numAsStr;
}
1
string number_to_string(int x){
    if(!x) return "0";
        string s,s2;
        while(x){
            s.push_back(x%10 + '0');
            x/=10;
        }
    reverse(s.begin(),s.end());
    return s;
}
1

Использование CString:

int a = 10;
CString strA;
strA.Format("%d", a);
  • 6
    Следует отметить, что это расширение только для Microsoft: msdn.microsoft.com/en-us/library/ms174288.aspx
  • 1
    Мне нравится идея CString :: Format (). К сожалению, это не переносимый MS только.
1

Я использую:

int myint = 0;
long double myLD = 0.0;

string myint_str = static_cast<ostringstream*>( &(ostringstream() << myint) )->str();
string myLD_str = static_cast<ostringstream*>( &(ostringstream() << myLD) )->str();

Он работает на моих компиляторах windows и linux g++.

1
namespace std
{
    inline string to_string(int _Val)
    {   // convert long long to string
        char _Buf[2 * _MAX_INT_DIG];
        snprintf(_Buf, "%d", _Val);
        return (string(_Buf));
    }
}

теперь вы можете использовать to_string(5)

  • 6
    Хотя это решение работает, оно крайне не рекомендуется! Имена, начинающиеся с подчеркивания и заглавной буквы, зарезервированы для компилятора, вы никогда не должны их использовать. Внедрение функций в пространство имен std - это тоже не то, что вы должны делать. Кроме того, не похоже, что _MAX_INT_DIG является стандартным макросом, поэтому, если он определен неправильно, этот код обладает большим потенциалом вызывать неопределенное поведение. -1
  • 5
    Что такое _MAX_INT_DIG и почему оно удвоено?
0

Я думаю, использование stringstream довольно просто.

 string toString(int n)
 {
   stringstream ss(n);
   ss << n;
   return ss.str();
 }

 int main()
 {
    int n;
    cin>>n;
    cout<<toString(n)<<endl;
    return 0;
 }
0
int n = 123;
std::string str = std::to_string(n);
  • 3
    Привет! Не могли бы вы добавить объяснение, почему и как это дает ответ на вопрос?
0

Вот еще один простой способ сделать

char str[100] ; 
sprintf(str , "%d" , 101 ) ;  
string s = str; 

sprintf является хорошо известным для вставки любых данных в строку требуемого формата.

Вы можете преобразовать char * array в строку, как показано в третьей строке.

0

Если вам требуется быстрое преобразование целого числа с фиксированным числом цифр в char * слева от "0", это удобный пример:

int n = 27;
char s[8];

Если вы преобразуете двузначное число:

*(int32_t*)s = 0x3030 | (n/10) | (n%10) << 8;

Если вы преобразуете трехзначное число:

*(int32_t*)s = 0x303030 | (n/100) | (n/10%10) << 8 | (n%10) << 16;

Если вы преобразуете четырехзначное число:

*(int64_t*)s = 0x30303030 | (n/1000) | (n/100%10)<<8 | (n/10%10)<<16 | (n%10)<<24;

И так далее до семизначных чисел:)

  • 0
    Как насчет порядка байтов?
0
char * bufSecs = new char[32];
char * bufMs = new char[32];
sprintf(bufSecs,"%d",timeStart.elapsed()/1000);
sprintf(bufMs,"%d",timeStart.elapsed()%1000);
  • 5
    утечки памяти -1 у меня
  • 5
    @ paulm верно. плюс -1 за создание чего-то бессмысленного осмысленного фрагмента откуда-то ...
-2

Вы используете алгоритм счетчика для преобразования в строку. Я получил эту технику от программирования Commodore 64. Это также полезно для игрового программирования.

  • Вы берете целое число и берете каждую цифру, взвешенную степенями 10. Предположим, что целое число равно 950.

    • Если целое число равно или превышает 100 000, то вычесть 100 000 и увеличить счетчик в строке в [ "000000" ];
      продолжайте делать это, пока не будет больше номеров в позиции 100 000. Отбросьте еще одну мощность из десяти

    • Если целое число равно или превышает 10000, то вычесть 10 000 и увеличить счетчик в строке в позиции [ "000000" ] + 1;
      продолжайте делать это, пока не будет больше номеров в позиции 10000.

  • Отбросьте еще одну мощность из десяти

  • Повторить шаблон

Я знаю, что 950 слишком мало для использования в качестве примера, но я надеюсь, что вы поняли эту идею.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню