¿Cuál es la forma más fácil de convertir int
a equivalente string
en C ++? Soy consciente de dos métodos. ¿Hay alguna manera más fácil?
(1)
int a = 10;
char *intStr = itoa(a);
string str = string(intStr);
(2)
int a = 10;
stringstream ss;
ss << a;
string str = ss.str();
c++
string
int
type-conversion
Nemo
fuente
fuente
itoa()
toma tres parámetros.Respuestas:
C ++ 11 introduce
std::stoi
(y variantes para cada tipo numérico) ystd::to_string
, las contrapartes de Catoi
y,itoa
pero se expresa en términos destd::string
.es, por lo tanto, el camino más corto que se me ocurre. Incluso puede omitir nombrar el tipo, usando la
auto
palabra clave:Nota: ver [string.conversions] ( 21.5 en n3242 )
fuente
to_string
no es miembro de lastd
solución: stackoverflow.com/questions/12975341/…g++ -std=c++11 someFile.cc
std
todos los compiladores que conozco, excepto uno.Error : No instance of overloaded function "std::to_string" matches the argument list
estoy usando VS2010 c ++string s = to_string((_ULonglong)i);
Comenzando una discusión con @ v.oddou un par de años más tarde, C ++ 17 finalmente ha entregado una forma de hacer la solución agnóstica de tipo originalmente basada en macro (preservada a continuación) sin pasar por la fealdad macro.
Uso:
Respuesta original:
Como "convertir ... a cadena" es un problema recurrente, siempre defino la macro SSTR () en un encabezado central de mis fuentes C ++:
El uso es tan fácil como podría ser:
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 Boostlexical_cast<>
); Sin embargo, estas otras dos soluciones tienen un mejor rendimiento.fuente
dynamic_cast
pero estoy usando clang para compilar, por lo que se queja. Si solo omito el,dynamic_cast
entonces se compila bien; ¿Para qué sirve eldynamic_cast
en este caso? Ya estamos creando unostringstream
, así que ¿por qué lanzarlo?ostringstream
, lo llamamosoperator<<()
, lo que devuelveostream &
, para lo cual.str()
no está definido. Realmente me pregunto cómo Clang haría que esto funcione sin el elenco (o por qué genera un error con él). Este constructo se publica en muchos lugares, y lo 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 escucharlo.do { } while( 0 )
no agregaría nada. Con 2. y 3. probablemente obtuviste un punto: esto podría hacerse con un reparto estático, y quizás uno de los asistentes de plantillas podría tener una interfaz "más agradable". Pero como dije, esto de ninguna manera es un invento mío. Mire a su alrededor, esta macro (¡macro!) Es bastante ubicua. Ese es un caso de POLA en sí mismo. Podría jugar con esto un poco para hacerlo más "aerodinámico".Usualmente uso el siguiente método:
Se describe en detalles aquí .
fuente
ss
, lo necesitasss.clear()
. He visto resultados inesperados sin esta inicialización.clear()
unostringstream
objeto recién creado .clear()
restablece los indicadores de error / eof y todavía no se ha generado ninguna condición de error / eof.NumberToString(23213.123)
produce23213.1
mientrasstd::to_string(23213.123)
produce23213.123000
¿Qué sucede allí?Probablemente la forma fácil más común envuelve esencialmente su segunda opción en una plantilla llamada
lexical_cast
, como la de Boost , por lo que su código se ve así:Una ventaja de esto es que también admite otros lanzamientos (por ejemplo, en la dirección opuesta funciona igual de bien).
También tenga en cuenta que, aunque Boost lexical_cast comenzó como escribir en un flujo de cadena y luego extraerlo de la transmisión, ahora tiene un par de adiciones. En primer lugar, se han agregado especializaciones para bastantes tipos, por lo que para muchos tipos comunes, es sustancialmente más rápido que usar un flujo de cadena. En segundo lugar, ahora comprueba el resultado, por lo que (por ejemplo) si convierte de una cadena a una
int
, puede lanzar una excepción si la cadena contiene algo que no se pudo convertir a unaint
(por ejemplo,1234
tendría éxito, pero123abc
arrojaría) .A partir de C ++ 11, hay una
std::to_string
función sobrecargada para los tipos enteros, por lo que puede usar código como:El estándar define estos como equivalentes a realizar la conversión con
sprintf
(utilizando el especificador de conversión que coincide con el tipo de objeto suministrado, como%d
forint
), en un búfer de tamaño suficiente, y luego crear unostd::string
de los contenidos de ese búfer.fuente
Si tiene instalado Boost (que debería):
fuente
Sería más fácil usar stringstreams:
O hacer una función:
fuente
No que yo sepa, en puro C ++. Pero una pequeña modificación de lo que mencionaste
debería funcionar, y es bastante corto.
fuente
itoa()
¡No es una función estándar!Puede usar
std::to_string
disponible en C ++ 11 como lo sugiere Matthieu M .:O, si el rendimiento es crítico (por ejemplo, si realiza muchas conversiones), puede usarlo
fmt::format_int
desde la biblioteca {fmt} para convertir un entero astd::string
:O una cadena C:
Este último no realiza ninguna asignación de memoria dinámica y es más de 10 veces más rápido que
std::to_string
en los puntos de referencia de Boost Karma. Consulte Conversión de entero a cadena rápida en C ++ para obtener más detalles.Tenga en cuenta que ambos son seguros para subprocesos.
A diferencia
std::to_string
,fmt::format_int
no requiere C ++ 11 y funciona con cualquier compilador de C ++.Descargo de responsabilidad: soy el autor de la biblioteca {fmt}.
fuente
c_str()
devuelve un puntero a un búfer declarado dentro de lafmt::FormatInt
clase, por lo que el puntero devuelto no será válido en el punto y coma - vea también stackoverflow.com/questions/4214153/lifetime-of-temporariesstd::string::c_str()
(por lo tanto, el nombre). Si desea usarlo fuera de la expresión completa, construya un objeto.FormatInt f(42);
Luego puede usarlof.c_str()
sin peligro de que sea destruido.sprintf()
es bastante bueno para la conversión de formatos. Luego puede asignar la cadena C resultante a la cadena C ++ como lo hizo en 1.fuente
NULL
tamaño cero para obtener el tamaño de búfer necesario.snprintf
(tenga en cuenta el prefijo SNP ) ysprintf
(tenga en cuenta el prefijo SP ). Se pasa el tamaño al primero, y se cuida de no desbordarse, sin embargo, el segundo no conoce el tamaño del búfer y, por lo tanto, puede desbordarse.snprintf
variante primero y unasprintf
variante después de eso. Como el tamaño del búfer se conoce para entonces, las llamadas sesprintf
vuelven completamente seguras.Primero incluye:
Segundo agrega el método:
Use el método de esta manera:
o
fuente
¡Usar stringstream para la conversión de números es peligroso!
Ver http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/ donde dice que
operator<<
inserta la salida formateada.Dependiendo de su ubicación actual, un entero mayor de 3 dígitos podría convertirse en una cadena de 4 dígitos, agregando un separador de miles adicional.
Por ejemplo,
int = 1000
podría convertirse en una cadena1.001
. Esto podría hacer que las operaciones de comparación no funcionen en absoluto.Por lo tanto, recomendaría encarecidamente utilizar el
std::to_string
camino. Es más fácil y hace lo que esperas.Actualizado (ver comentarios a continuación) :
fuente
std::to_string
usa la configuración regional actual (consulte en.cppreference.com/w/cpp/string/basic_string/to_string , la sección 'Notas'). Casi todas las herramientas estándar (desde cadenas de secuencias hastasprintf
, pero tambiénsscanf
etc.) están utilizando la configuración regional actual. No era consciente de esto hasta hace poco, cuando me golpeó duro. Actualmente usando cosas de cosecha propia, no es difícil de hacer.Para C ++ 98 , hay algunas opciones:
boost/lexical_cast
Boost no es parte de la biblioteca de C ++, pero contiene muchas extensiones útiles de la biblioteca.
En cuanto al tiempo de ejecución, la
lexical_cast
operación tarda aproximadamente 80 microsegundos (en mi máquina) en la primera conversión, y luego se acelera considerablemente después si se realiza de forma redundante.itoa
Esto significa que
gcc
/g++
no puedo compilar código usandoitoa
.No hay tiempo de ejecución para informar. No tengo instalado Visual Studio, que según se informa puede compilar
itoa
.sprintf
sprintf
es una función de biblioteca estándar C que funciona en cadenas C, y es una alternativa perfectamente válida.El
stdio.h
encabezado puede no ser necesario. En cuanto al tiempo de ejecución, lasprintf
operación tarda unos 40 microsegundos (en mi máquina) en la primera conversión, y luego se acelera considerablemente después si se realiza de forma redundante.stringstream
Esta es la forma principal de la biblioteca C ++ de convertir enteros en cadenas, y viceversa. Hay funciones hermanas similares
stringstream
que limitan aún más el uso previsto de la transmisión, comoostringstream
. El usoostringstream
le dice específicamente al lector de su código que solo tiene la intención de utilizar el<<
operador, esencialmente. Esta función es todo lo que es particularmente necesario para convertir un entero en una cadena. Vea esta pregunta para una discusión más elaborada.En cuanto al tiempo de ejecución, la
ostringstream
operación tarda aproximadamente 71 microsegundos (en mi máquina) y luego se acelera considerablemente si se realiza de forma redundante, pero no tanto como las funciones anteriores .Por supuesto, hay otras opciones, e incluso puede incluir una de ellas en su propia función, pero esto ofrece una visión analítica de algunas de las más populares.
fuente
C ++ 17 proporciona std :: to_chars como una alternativa independiente del entorno de mayor rendimiento.
fuente
Es bastante fácil agregar un poco de azúcar sintáctica que le permite a uno componer cadenas sobre la marcha de una manera similar a una secuencia.
Ahora puede agregar lo que desee (siempre que
<< (std::ostream& ..)
se haya definido un operador )strmake()
y usarlo en lugar de unstd::string
.Ejemplo:
fuente
EDITADO Si necesita una conversión rápida de un número entero con un número fijo de dígitos a char * rellenado a la izquierda con '0' , este es el ejemplo para arquitecturas little endian (todas x86, x86_64 y otras):
Si está convirtiendo un número de dos dígitos:
Si está convirtiendo un número de tres dígitos:
Si está convirtiendo un número de cuatro dígitos:
Y así sucesivamente hasta números de siete dígitos. En este ejemplo
n
es un entero dado. Después de la conversión, se puede acceder a su representación de cadena como(char*)&s
:NOTA: Si lo necesita en orden de bytes big-endian, aunque no lo probé, pero aquí hay un ejemplo: para un número de tres dígitos es
int32_t s = 0x00303030 | (n/100)<< 24 | (n/10%10)<<16 | (n%10)<<8;
para números de cuatro dígitos (arco de 64 bits):int64_t s = 0x0000000030303030 | (n/1000)<<56 | (n/100%10)<<48 | (n/10%10)<<40 | (n%10)<<32;
creo que debería funcionar.fuente
Utilizar:
fuente
Yo suelo:
Funciona en mis compiladores g ++ de Windows y Linux.
fuente
sprintf
es bien conocido para insertar cualquier dato en una cadena del formato requerido.Puede convertir una
char *
matriz en una cadena como se muestra en la tercera línea.fuente
Esto funcionó para mí
Mi código:
fuente
stringstream
?std::to_string()
using namespace std;
:)C ++ 11 introducido
std::to_string()
para tipos numéricos:fuente
Utilizar:
fuente
fuente
Si usa MFC , puede usar
CString
:fuente
fuente
Ahora puedes usar
to_string(5)
.fuente
std
espacio de nombres tampoco es algo que deba hacer. Además, no parece que_MAX_INT_DIG
sea una macro estándar, por lo que si se define incorrectamente, este código tiene el gran potencial de inducir un comportamiento indefinido. -1Creo que usar
stringstream
es bastante fácil:fuente
Utiliza un algoritmo de tipo contador para convertir en una cadena. Obtuve esta técnica de la programación de las computadoras Commodore 64 . También es bueno para la programación de juegos.
Tomas el número entero y tomas cada dígito ponderado por potencias de 10. Así que asume que el número entero es 950.
Si el número entero es igual o mayor que 100,000, reste 100,000 y aumente el contador en la cadena en ["000000"];
sigue haciéndolo hasta que no haya más números en la posición 100,000. Suelta otro poder de diez.
Si el número entero es igual o mayor que 10,000, reste 10,000 y aumente el contador en la cadena en ["000000"] + 1 posición;
sigue haciéndolo hasta que no haya más números en la posición 10,000.
Suelta otro poder de diez
Sé que el 950 es demasiado pequeño para usarlo como ejemplo, pero espero que entiendas la idea.
fuente