como converter de int para char *?


98

A única maneira que sei é:

#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();
}

Mas existe algum método com menos digitação?


8
por que você quer uma string C em vez de uma string C ++?
KillianDS de

1
use sprintf
Kasma

Respostas:


128
  • Em C ++ 17, use std::to_charscomo:

    std::array<char, 10> str;
    std::to_chars(str.data(), str.data() + str.size(), 42);
  • Em C ++ 11, use std::to_stringcomo:

    std::string s = std::to_string(number);
    char const *pchar = s.c_str();  //use char const* as target type
  • E em C ++ 03, o que você está fazendo é ótimo, exceto usar constcomo:

    char const* pchar = temp_str.c_str(); //dont use cast

1
A primeira parte não responde realmente à pergunta (embora seja uma boa informação útil, pois eu não estava ciente dessa função)
jcoder

1
Melhor :) Além disso, é melhor eu ler mais sobre c ++ 11 novamente. Eu sei sobre os grandes recursos, mas isso me fez perceber que provavelmente há mais pequenos que eu perdi.
jcoder 01 de

1
@Adambean: Por que "não deve envolver std :: string"? . Deve-se usar std::stringpor padrão, em vez de char*.
Nawaz

1
std :: string nem sempre está disponível, particularmente para projetos mais antigos. Muitos jogos C ++ também permanecem longe de std :: string. Ir de int para std :: string para char * não é o mesmo que int para char *.
Adambean

1
@Adambean: Se for C ++, assumirei que std::stringestá disponível por padrão, a menos que seja explicitamente especificado na própria pergunta. Faz sentido? Além disso, como a própria pergunta usa std::string(e std::stringstream), você não tem muitos motivos para discordar dela.
Nawaz

11

Acho que você pode usar um sprintf:

int number = 33;
char* numberstring[(((sizeof number) * CHAR_BIT) + 2)/3 + 2];
sprintf(numberstring, "%d", number);

1
você deve alterar char * para char, agora numberstring é um array de ponteiros
josefx

1
Além disso, você precisa de 12 caracteres para converter um inteiro de 32 bits em uma representação de base 10 terminada em nulo. 10 não é suficiente para -2147483647.
Steve Jessop

11
Que tal alguma explicação? (((sizeof number) * CHAR_BIT) + 2)/3 + 2parece magia ...
Mike S

7

Você pode usar impulso

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

5

A solução de estilo C pode ser usada itoa, mas a melhor maneira é imprimir esse número em uma string usando sprintf/snprintf . Verifique esta questão: Como converter um número inteiro em uma string de forma portátil?

Observe que a itoafunção não é definida em ANSI-C e não faz parte do C ++, mas é compatível com alguns compiladores. É uma função fora do padrão, portanto, você deve evitar usá-la. Verifique esta questão também: Alternativa para itoa () para converter inteiros em strings C ++?

Observe também que escrever código no estilo C durante a programação em C ++ é considerado uma prática ruim e, às vezes, referido como "estilo horrível". Você realmente deseja convertê-lo em char*string estilo C ? :)


5

Eu não descartaria o const na última linha, pois ele existe por um motivo. Se você não consegue viver com um const char *, é melhor copiar a matriz char como:

char* char_type = new char[temp_str.length()];
strcpy(char_type, temp_str.c_str());

você quer dizer const char* char_type = temp_str.c_str();é melhor?
rsk82

1
Sim. c_str fornece um ponteiro para o buffer interno do objeto string. Se você descartar o const, você ou outro programador pode pensar que não há problema em alterar o buffer por meio da variável não const. Mas não é. O objeto string original não sabe nada sobre essas mudanças. Por outro lado, a string ainda possui o buffer. Se o objeto string sair do escopo, a memória atrás do ponteiro é excluída pelo destruidor dos objetos string, deixando você com um ponteiro pendurado. A operação de cópia remove ambos os 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];. Isso fornece memória mutável, embora, é claro, você ainda precise manter o vetor vivo pelo tempo que quiser usar o ponteiro.
Steve Jessop

1
Ou apenas use stringe não se preocupe com o velho, simples, estúpido char *do velho, puro C. <bits de chama pretendidos>
Griwes

@Griwes: a questão é como chegar char*, não "há algum ponto em chamar de C ++ para bibliotecas existentes escritas em C, ou devo reimplementá-las em C ++?" ;-p
Steve Jessop

2

Tudo bem ... primeiro eu precisava de algo que fizesse o que esta pergunta está pedindo, mas eu precisava RAPIDAMENTE! Infelizmente, a maneira "melhor" é quase 600 linhas de código !!! Perdoe o nome disso que não tem nada a ver com o que está fazendo. O nome próprio era Integer64ToCharArray (valor int64_t);

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

Sinta-se à vontade para tentar limpar esse código sem prejudicar o desempenho.

Entrada: qualquer valor com sinal de 64 bits do intervalo mínimo ao máximo.

Exemplo:

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

Resultado:

Test: 9223372036854775807
Test: -9223372036854775808

Testes de velocidade originais: ( Integer64ToCharArray (); )

Melhor caso, valor de 1 dígito.

Loops: 100.000.000, Tempo gasto: 1.381 (Milli), Tempo por Loop 13 (Nano)

Pior caso, valor de 20 dígitos.

Loops: 100.000.000, tempo gasto: 22.656 (Milli), Tempo por loop 226 (Nano

Novos testes de velocidade de design: ( AddDynamicallyToBuffer (); )

Melhor caso, valor de 1 dígito.

Loops: 100.000.000, Tempo gasto: 427 (Milli), Tempo por Loop 4 (Nano)

Pior caso de 32 bits - valor de 11 dígitos.

Loops: 100.000.000, Tempo gasto: 1.991 (Milli), Tempo por Loop 19 (Nano)

Pior caso negativo de 1 trilhão - valor de 14 dígitos.

Loops: 100.000.000, Tempo gasto: 5.681 (Milli), Tempo por Loop 56 (Nano)

Pior caso de 64 bits - valor de 20 dígitos.

Loops: 100.000.000, Tempo gasto: 13.148 (Milli), Tempo por Loop 131 (Nano)

Como funciona!

Executamos uma técnica de divisão e conquista e, uma vez que definimos o comprimento máximo da string, simplesmente definimos cada valor de caractere individualmente. Conforme mostrado nos testes de velocidade acima, os comprimentos maiores obtêm grandes penalidades de desempenho, mas ainda é muito mais rápido do que o método de loop original e nenhum código realmente mudou entre os dois métodos, exceto o looping não está mais em uso.

Em meu uso, daí o nome, eu retorno o deslocamento e não edito um buffer de matrizes de caracteres, em vez disso, começo a atualizar os dados de vértice e a função tem um parâmetro adicional para deslocamento, portanto, não é inicializada como -1.




0

Você também pode usar o elenco.

exemplo:

string s;
int value = 3;
s.push_back((char)('0' + value));

1
E se o valor for negativo ou não for um dígito?
Ziya ERKOC
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.