Cómo convertir int a cadena en C++

8 minutos de lectura

Avatar de usuario de Nemo
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();

  • 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

Avatar de usuario de DevSolar
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 el dynamic_cast entonces compila bien; que proposito tiene el dynamic_cast sirve en este caso? Ya estamos creando un ostringstreamentonces, ¿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 ostringstreamllamamos operator<<() en ella, que vuelve ostream & — 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

Avatar de usuario de Rasoul
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 creado ostringstream 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) produce 23213.1 mientras std::to_string(23213.123) produce 23213.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 creado ostringstream 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) produce 23213.1 mientras std::to_string(23213.123) produce 23213.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

Avatar de usuario de Peter Mortensen
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


¿Ha sido útil esta solución?