¿Cómo convertir de int a char *?

98

La única forma que conozco es:

#include <sstream>
#include <string.h>
using namespace std;

int main() {
  int number=33;
  stringstream strs;
  strs << number;
  string temp_str = strs.str();
  char* char_type = (char*) temp_str.c_str();
}

¿Pero hay algún método con menos escritura?

rsk82
fuente
8
¿Por qué quieres una cadena C en lugar de una cadena C ++?
KillianDS
1
use sprintf
Kasma

Respuestas:

128
  • En C ++ 17, utilícelo std::to_charscomo:

    std::array<char, 10> str;
    std::to_chars(str.data(), str.data() + str.size(), 42);
    
  • En C ++ 11, utilícelo std::to_stringcomo:

    std::string s = std::to_string(number);
    char const *pchar = s.c_str();  //use char const* as target type
    
  • Y en C ++ 03, lo que está haciendo está bien, excepto que se usa constcomo:

    char const* pchar = temp_str.c_str(); //dont use cast
Nawaz
fuente
1
La primera parte en realidad no responde a la pregunta (aunque es una buena información útil ya que no estaba al tanto de esa función)
jcoder
1
Mejor :) Además, será mejor que vuelva a leer más sobre c ++ 11. Conozco las grandes funciones, pero esto me ha hecho darme cuenta de que probablemente haya más pequeñas que me perdí.
jcoder
1
@Adambean: ¿Por qué "no debería involucrar std :: string"? . Uno debería usar std::stringpor defecto, en lugar de char*.
Nawaz
1
std :: string no siempre está disponible, particularmente para proyectos más antiguos. Muchos juegos de C ++ también se mantienen alejados de std :: string. Pasar de int a std :: string a char * no es lo mismo que int a char *.
Adambean
1
@Adambean: Si es C ++, asumiré que std::stringestá disponible de forma predeterminada, a menos que se especifique explícitamente en la pregunta. ¿Tiene sentido? Además, dado que la pregunta en sí usa std::string(y std::stringstream), no tiene muchas razones para no estar de acuerdo con ella.
Nawaz
11

Creo que puedes usar un sprintf:

int number = 33;
char* numberstring[(((sizeof number) * CHAR_BIT) + 2)/3 + 2];
sprintf(numberstring, "%d", number);
Pierre Pellegrino Milza
fuente
1
debe cambiar char * a char, en este momento la cadena de números es una matriz de punteros
josefx
1
Además, necesita 12 caracteres para convertir un entero de 32 bits en una representación en base 10 terminada en nulo. 10 no es suficiente para -2147483647.
Steve Jessop
11
¿Qué tal alguna explicación? (((sizeof number) * CHAR_BIT) + 2)/3 + 2parece hechicería ...
Mike S
7

Puedes usar boost

#include <boost/lexical_cast.hpp>
string s = boost::lexical_cast<string>( number );
maverik
fuente
5

La solución de estilo C podría ser usar itoa, pero la mejor manera es imprimir este número en una cadena usando sprintf/snprintf . Compruebe esta pregunta: ¿Cómo convertir un número entero en una cadena de forma portátil?

Tenga en cuenta que la itoafunción no está definida en ANSI-C y no es parte de C ++, pero es compatible con algunos compiladores. Es una función no estándar, por lo que debe evitar su uso. Compruebe también esta pregunta: ¿ alternativa a itoa () para convertir un entero en una cadena C ++?

También tenga en cuenta que escribir código de estilo C mientras se programa en C ++ se considera una mala práctica y, a veces, se lo denomina "estilo espantoso". ¿Realmente quieres convertirlo en una char*cadena de estilo C ? :)

LihO
fuente
5

No encasillaría la const en la última línea ya que está ahí por una razón. Si no puede vivir con un char * const, entonces es mejor que copie la matriz char como:

char* char_type = new char[temp_str.length()];
strcpy(char_type, temp_str.c_str());
user331471
fuente
¿Quieres decir que const char* char_type = temp_str.c_str();es mejor?
rsk82
1
Si. c_str le da un puntero al búfer interno del objeto de cadena. Si descarta la constante, usted u otro programador podrían pensar que está bien cambiar el búfer a través de la variable no constante. Pero no lo es. El objeto de cadena original no sabe nada sobre estos cambios. Por otro lado, la cadena sigue siendo propietaria del búfer. Si el objeto de cadena sale del alcance, el destructor de objetos de cadena borra la memoria detrás del puntero, dejándolo con un puntero colgando. La operación de copia elimina ambos problemas.
user331471
1
Alternativamente, std::vector<char> temp_vec(temp_str.begin(), temp_str.end()); temp_vec.push_back(0); char *char_type = &vec[0];. Esto le brinda memoria mutable, aunque, por supuesto, aún necesita mantener vivo el vector durante el tiempo que desee usar el puntero.
Steve Jessop
1
O simplemente use stringy no se moleste con la vieja, simple, estúpida char *de la vieja, simple C. <se pretenden trozos de llama>
Griwes
@Griwes: la pregunta es cómo llegar char*, no "¿tiene algún sentido llamar desde C ++ a bibliotecas existentes escritas en C, o debería volver a implementarlas en C ++?" ;-p
Steve Jessop
2

Muy bien ... en primer lugar, necesitaba algo que hiciera lo que esta pregunta es, ¡pero lo necesitaba RÁPIDO! Desafortunadamente, la forma "mejor" es de casi 600 líneas de código. Perdone el nombre que no tiene nada que ver con lo que está haciendo. El nombre correcto era Integer64ToCharArray (valor int64_t);

https://github.com/JeremyDX/All-Language-Testing-Code/blob/master/C%2B%2B%20Examples/IntegerToCharArrayTesting.cpp

Siéntase libre de intentar limpiar ese código sin afectar el rendimiento.

Entrada: cualquier valor de 64 bits con signo desde el rango mínimo al máximo.

Ejemplo:

std::cout << "Test: " << AddDynamicallyToBuffer(LLONG_MAX) << '\n';
std::cout << "Test: " << AddDynamicallyToBuffer(LLONG_MIN) << '\n';

Salida:

Test: 9223372036854775807
Test: -9223372036854775808

Pruebas de velocidad originales: ( Integer64ToCharArray (); )

En el mejor de los casos, valor de 1 dígito.

Bucles: 100,000,000, tiempo empleado: 1,381 (Milli), tiempo por bucle 13 (Nano)

En el peor de los casos, valor de 20 dígitos.

Bucles: 100,000,000, tiempo invertido: 22,656 (Milli), tiempo por bucle 226 (Nano

Nuevas pruebas de velocidad de diseño: ( AddDynamicallyToBuffer (); )

En el mejor de los casos, valor de 1 dígito.

Bucles: 100.000.000, tiempo empleado: 427 (Milli), tiempo por bucle 4 (nano)

Peor caso de 32 bits: valor de 11 dígitos.

Bucles: 100,000,000, tiempo empleado: 1,991 (Milli), tiempo por bucle 19 (nano)

1 billón negativo en el peor de los casos: valor de 14 dígitos.

Bucles: 100,000,000, tiempo empleado: 5,681 (Milli), tiempo por bucle 56 (Nano)

64 bits en el peor de los casos: valor de 20 dígitos.

Bucles: 100,000,000, tiempo empleado: 13,148 (Milli), tiempo por bucle 131 (Nano)

¡Cómo funciona!

Realizamos una técnica de Divide and Conquer y una vez que tenemos la longitud máxima de la cadena, simplemente establecemos el valor de cada carácter individualmente. Como se muestra en las pruebas de velocidad anteriores, las longitudes más grandes tienen grandes penalizaciones de rendimiento, pero aún es mucho más rápido que el método de bucle original y ningún código ha cambiado entre los dos métodos, además de que el bucle ya no está en uso.

En mi uso, de ahí el nombre, devuelvo el desplazamiento en su lugar y no edito un búfer de matrices de caracteres, sino que comienzo a actualizar los datos de vértice y la función tiene un parámetro adicional para el desplazamiento, por lo que no se inicializa en -1.

Jeremy Trifilo
fuente
0

También puedes usar el casting.

ejemplo:

string s;
int value = 3;
s.push_back((char)('0' + value));
elmaystro
fuente
1
¿Qué pasa si el valor es negativo o no es un dígito?
Ziya ERKOC