Nemo
¿Cómo puedo convertir de int
al equivalente string
en C++? Conozco dos métodos. ¿Hay otra manera?
(1)
int a = 10;
char *intStr = itoa(a);
string str = string(intStr);
(2)
int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
DevSolar
C++20: estándar::formato sería la forma idiomática ahora.
C++17:
Retomando una discusión con @v.oddou un par de años más tarde, C++17 ha proporcionado una forma de hacer la solución independiente de tipo basada originalmente en macros (conservada a continuación) sin pasando por macrofealdad.
// variadic template
template < typename... Args >
std::string sstr( Args &&... args )
{
std::ostringstream sstr;
// fold expression
( sstr << std::dec << ... << args );
return sstr.str();
}
Uso:
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:
Dado que “convertir … a cadena” es un problema recurrente, siempre defino el SSTR() macro en un encabezado central de mis fuentes de C++:
#include <sstream>
#define SSTR( x ) static_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
El uso es tan fácil como podría ser:
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 ) );
Lo anterior es compatible con C++98 (si no puede usar C++11 std::to_string
), y no necesita ninguna inclusión de terceros (si no puede usar Boost lexical_cast<>
); Sin embargo, estas otras dos soluciones tienen un mejor rendimiento.
-
no estoy muy familiarizado con
dynamic_cast
pero estoy usando clang para compilar, por lo que se queja. Si simplemente omito eldynamic_cast
entonces compila bien; que proposito tiene eldynamic_cast
sirve en este caso? Ya estamos creando unostringstream
entonces, ¿por qué lanzarlo?– Mateo
21 de octubre de 2014 a las 2:38
-
@Mathew: el enlace en mi respuesta conduce a una descripción detallada de cada parte de la construcción. Mientras nosotros creado a
ostringstream
llamamosoperator<<()
en ella, que vuelveostream &
— para cual.str()
no está definido. Realmente me pregunto cómo clang haría que esto funcionara sin el elenco (o por qué genera un error con él). Esta construcción se publica en muchos lugares, y la he usado durante más de una década en muchos compiladores diferentes, incluidos MSVC, GCC y XLC, por lo que estoy bastante sorprendido de que se oponga a ella.– DevSolar
21 de octubre de 2014 a las 6:59
-
Solo vine a la fiesta por curiosidad y voté negativo. Motivo: demasiados votos para una solución poco elegante y probablemente lenta. 1. uso de macros. No frunzo el ceño sistemáticamente con ninguna macro, pero esta es demasiado corta y los clientes finales siempre temen la repetición del argumento, además del miedo a las macros multilínea desprotegidas. (no protegido por do{}while(0)) 2. dynamic_cast. parece que solo necesita un static_cast aquí, a menos que quiera afirmar que la biblioteca está implementada como espera. en cuyo caso deberías usar boost::polymorphic_downcast en su lugar.
– v.oddou
18 de junio de 2015 a las 3:30
-
@v.oddou: Eres libre de criticar, por supuesto. Pero 1. no es válido: la macro es una declaración única,
do { } while( 0 )
no agregaria nada. Con 2. y 3. probablemente entendiste un punto: esto podría hacerse con un molde estático, y quizás uno de los magos de las plantillas podría crear una interfaz “más agradable”. Pero como dije, esto de ninguna manera es una invención mía. Mire a su alrededor, esta macro (¡macro!) es bastante omnipresente. Ese es un caso de POLA en sí mismo. Podría jugar un poco con esto para hacerlo más “simplificado”.– DevSolar
18 de junio de 2015 a las 8:45
-
@v.oddou: Mira lo que encontré entre las cosas que C++17 nos trajo. 🙂 Espero que les guste la respuesta actualizada.
– DevSolar
13 mayo 2018 a las 20:57
-
Bien, prefiero la respuesta de Kevin, aunque muestra el espacio de nombres y de inclusión. Solo una queja menor. 🙂 ¡Buen trabajo, sin embargo!
– Jason R.Mick
21 de marzo de 2013 a las 14:15
-
Diría que este es el camino a seguir si no tiene soporte para C++ 11.
– Alejandro Ah
21 de junio de 2013 a las 8:16
Rasoul
Usualmente uso el siguiente método:
#include <sstream>
template <typename T>
std::string NumberToString ( T Number )
{
std::ostringstream ss;
ss << Number;
return ss.str();
}
Se describe en detalle aquí.
-
@lifebalance: Nunca he visto tal comportamiento.
– Rasul
11 de junio de 2015 a las 8:23
-
@lifebalance: No es necesario
clear()
un recién creadoostringstream
objeto.clear()
restablece los indicadores de error/eof, y aún no se ha generado ninguna condición de error/eof.– Rémy Lebeau
5 de agosto de 2015 a las 4:00
-
@Rasoul
NumberToString(23213.123)
produce23213.1
mientrasstd::to_string(23213.123)
produce23213.123000
¿Qué sucede allí?– Killzone Kid
5 noviembre 2017 a las 23:00
-
Normalmente no escribiría una función para tres líneas, pero lo hace autodocumentado a través del nombre. Claridad frente a autodocumentación: no deberían entrar en conflicto, ¿verdad?
– forgan1
23 de noviembre de 2018 a las 2:04
-
@KillzoneKid Esto se debe a que std’ ostream tiene estado (esto significa que se mantiene cualquier cambio de estado anterior, como el número de dígitos decimales) mientras que este método comienza con un estado predeterminado.
– xryl669
14 de junio de 2019 a las 14:04
Puedes usar std::to_string
disponible en C++ 11 según lo sugerido por Matthieu M.:
std::string s = std::to_string(42);
O bien, si el rendimiento es fundamental (por ejemplo, si realiza muchas conversiones), puede utilizar fmt::format_int
desde el {mt} biblioteca para convertir un número entero a std::string
:
std::string s = fmt::format_int(42).str();
O una cadena C:
fmt::format_int f(42);
const char* s = f.c_str();
Este último no realiza ninguna asignación de memoria dinámica y es un 70 % más rápido que la implementación de libstdc++ de std::to_string
en los puntos de referencia de Boost Karma. Ver Convertir cien millones de enteros a cadenas por segundo para más detalles.
Descargo de responsabilidad: soy el autor de la biblioteca {fmt}.
-
@lifebalance: Nunca he visto tal comportamiento.
– Rasul
11 de junio de 2015 a las 8:23
-
@lifebalance: No es necesario
clear()
un recién creadoostringstream
objeto.clear()
restablece los indicadores de error/eof, y aún no se ha generado ninguna condición de error/eof.– Rémy Lebeau
5 de agosto de 2015 a las 4:00
-
@Rasoul
NumberToString(23213.123)
produce23213.1
mientrasstd::to_string(23213.123)
produce23213.123000
¿Qué sucede allí?– Killzone Kid
5 noviembre 2017 a las 23:00
-
Normalmente no escribiría una función para tres líneas, pero lo hace autodocumentado a través del nombre. Claridad frente a autodocumentación: no deberían entrar en conflicto, ¿verdad?
– forgan1
23 de noviembre de 2018 a las 2:04
-
@KillzoneKid Esto se debe a que std’ ostream tiene estado (esto significa que se mantiene cualquier cambio de estado anterior, como el número de dígitos decimales) mientras que este método comienza con un estado predeterminado.
– xryl669
14 de junio de 2019 a las 14:04
Pedro Mortensen
Si usted tiene Aumentar instalado (que deberías):
#include <boost/lexical_cast.hpp>
int num = 4;
std::string str = boost::lexical_cast<std::string>(num);
-
Acordado instalación boost. Creo que más a menudo uno formatearía la cadena. Para este propósito, prefiero boost::format, por ejemplo, format(“%02d”, number ).str()
– Werner Erasmo
28 de agosto de 2013 a las 18:47
Creo que los dos métodos que diste son buenas soluciones. depende del contexto donde necesites hacerlo. Si ya está trabajando con transmisiones, por ejemplo, leyendo o escribiendo un archivo, entonces su segundo método es el mejor. Si necesita pasar un int como una cadena a un argumento de función, entonces itoa podría ser una manera fácil. Pero la mayoría de las veces, la conversión de int a cadena ocurre cuando se trata de archivos, por lo que las secuencias son apropiadas.
– Carlos Brunet
8 de abril de 2011 a las 5:21
¿Cómo funciona la opción 1 para ti? Tengo entendido que
itoa()
toma tres parámetros.– Arkon
10 de abril de 2013 a las 2:49
itoa será más rápido que el flujo equivalente. También hay formas de reutilizar el búfer de cadenas con el método itoa (evitando las asignaciones de montones si genera cadenas con frecuencia, por ejemplo, para algunos resultados numéricos que se actualizan rápidamente). Alternativamente, puede generar un streambuf personalizado para reducir algunos de los gastos generales de asignación, etc. Construir la transmisión en primer lugar tampoco es una empresa de bajo costo.
– Pete
28 de agosto de 2013 a las 18:46
@Pete: Una vez que comience a preocuparse por cuál es más rápido, querrá consultar stackoverflow.com/questions/4351371/…
– Ben Voigt
24/09/2013 a las 19:21
Tenga en cuenta que itoa() no es parte del estándar y, por lo tanto, usarlo hace que su código no sea portátil, ya que no todos los compiladores lo admiten. Para Linux, seguramente está fuera a menos que esté usando algo más que GCC, que no es compatible con esta función. Si tiene C++ 0x, siga lo que @Matthieu ha sugerido en su respuesta. Si ese no es el caso, opte por stringstream, ya que es una característica bien admitida y su código debe ser compatible con todos los compiladores de C++ que existen. Como alternativa, siempre puedes usar sprintf().
– rbaleksandar
16 de junio de 2014 a las 9:59