Jaký je nejjednodušší způsob převodu z int
na ekvivalentní string
v C++. Znám dvě metody. Existuje nějaký jednodušší způsob?
(1)
int a = 10;
char *intStr = itoa(a);
string str = string(intStr);
(2)
int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
Po několika letech jsme navázali na diskusi s @v.oddou a C++17 konečně přinesl způsob, jak provést původně typové řešení založené na makrech (zachované níže) bez ošklivosti maker.
// variadic template
template < typename... Args >
std::string sstr( Args &&... args )
{
std::ostringstream sstr;
// fold expression
( sstr << std::dec << ... << args );
return sstr.str();
}
Použití:
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 ) );
Původní odpověď:
Protože "převod ... na řetězec" je opakovaný problém, vždy definuji makro SSTR() v centrální hlavičce svých zdrojových kódů v C++:
#include <sstream>
#define SSTR( x ) static_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
Použití je tak snadné, jak jen může být:
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 ) );
Výše uvedené řešení je kompatibilní s C++98 (pokud nemůžete použít C++11 std::to_string
) a nepotřebuje žádné includy třetích stran (pokud nemůžete použít Boost lexical_cast<>
); obě tato řešení však mají lepší výkon.
Pravděpodobně nejběžnějším způsobem je zabalení druhé volby do šablony s názvem lexical_cast
, jako je například šablona v Boost, takže váš kód vypadá takto:
int a = 10;
string s = lexical_cast<string>(a);
Jednou z příjemných vlastností tohoto postupu je, že podporuje i jiná odhození (např. v opačném směru funguje stejně dobře).
Všimněte si také, že ačkoli Boost lexical_cast začínal jako pouhý zápis do řetězcového proudu a následné extrahování zpět z proudu, nyní má několik doplňků. Především byly přidány specializace pro poměrně dost typů, takže pro mnoho běžných typů je podstatně rychlejší než použití stringstreamu. Za druhé nyní kontroluje výsledek, takže (například) při převodu z řetězce na int
může vyhodit výjimku, pokud řetězec obsahuje něco, co se na int
převést nedalo (např. 1234
by se povedlo, ale 123abc
by vyhodilo).
Od verze C++11 existuje funkce std::to_string
přetížená pro celočíselné typy, takže můžete použít kód jako např:
int a = 20;
std::string s = to_string(a);
Standard je definuje jako ekvivalentní převodu pomocí sprintf
(s použitím převodního specifikátoru, který odpovídá zadanému typu objektu, například %d
pro int
) do bufferu dostatečné velikosti a následnému vytvoření std::string
z obsahu tohoto bufferu.