Який найпростіший спосіб перетворення з 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();
Підхопивши дискусію з @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
), і не потребує жодних сторонніх включень (якщо ви не можете використовувати Boost lexical_cast<>
); обидва ці рішення мають кращу продуктивність, однак.
Ймовірно, найпоширеніший простий спосіб полягає в тому, щоб обернути ваш другий варіант у шаблон з назвою lexical_cast
, як, наприклад, у Boost, таким чином, ваш код буде виглядати так:
int a = 10;
string s = lexical_cast<string>(a);
Однією з переваг цього методу є те, що він також підтримує інші касти (наприклад, у зворотному напрямку працює так само добре).
Також зауважте, що хоча Boost lexical_cast починався як простий запис у потік рядків, а потім вилучення назад з потоку, зараз він має декілька доповнень. По-перше, були додані спеціалізації для досить багатьох типів, так що для багатьох поширених типів це значно швидше, ніж використання рядкового потоку. По-друге, тепер він перевіряє результат, тому (наприклад) якщо ви перетворюєте з рядка в int
, він може згенерувати виключення, якщо рядок містить щось, що не може бути перетворено в int
(наприклад, 1234
пройде успішно, але 123abc
згенерує виключення).
Починаючи з C++11, функція std::to_string
перевантажена для цілих типів, тому ви можете використовувати код на зразок:
int a = 20;
std::string s = to_string(a);
Стандарт визначає, що це еквівалентно виконанню перетворення за допомогою sprintf
(з використанням специфікатора перетворення, який відповідає наданому типу об'єкта, наприклад, %d
для int
), у буфер достатнього розміру, а потім створення std::string
з вмісту цього буферу.