come convertire da int a char *?


98

L'unico modo che conosco è:

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

Ma esiste un metodo con meno battitura?


8
perché vuoi una stringa C invece di una stringa C ++?
KillianDS

1
usa sprintf
Kasma

Risposte:


128
  • In C ++ 17, usa std::to_charscome:

    std::array<char, 10> str;
    std::to_chars(str.data(), str.data() + str.size(), 42);
  • In C ++ 11, usa std::to_stringcome:

    std::string s = std::to_string(number);
    char const *pchar = s.c_str();  //use char const* as target type
  • E in C ++ 03, quello che stai facendo va bene, tranne per l'uso constcome:

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

1
La prima parte in realtà non risponde alla domanda (sebbene sia una buona informazione utile perché non ero a conoscenza di quella funzione)
jcoder

1
Meglio :) Inoltre è meglio che vada di nuovo a leggere di più su c ++ 11. Conosco le grandi funzionalità, ma questo mi ha fatto capire che probabilmente ce ne sono di più piccole che mi mancavano.
jcoder

1
@ Adambean: Perché "non dovrebbe coinvolgere std :: string"? . Uno dovrebbe usare std::stringper impostazione predefinita, invece di char*.
Nawaz

1
std :: string non è sempre disponibile, in particolare per i progetti più vecchi. Anche molti giochi C ++ restano lontani da std :: string. Passare da int a std :: string a char * non è la stessa cosa di int a char *.
Adambean

1
@Adambean: se è C ++, presumo che std::stringsia disponibile per impostazione predefinita, a meno che non sia esplicitamente specificato nella domanda stessa. Ha senso? Inoltre, poiché la domanda stessa utilizza std::string(e std::stringstream), non hai molte ragioni per non essere d'accordo.
Nawaz

11

Penso che tu possa usare uno sprintf:

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

1
dovresti cambiare char * in char, in questo momento la stringa numerica è un array di puntatori
josefx

1
Inoltre, sono necessari 12 caratteri per convertire un intero a 32 bit in una rappresentazione in base 10 con terminazione nul. 10 non è sufficiente per -2147483647.
Steve Jessop

11
Che ne dici di una spiegazione? (((sizeof number) * CHAR_BIT) + 2)/3 + 2sembra una magia ...
Mike S

7

Puoi usare boost

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

5

La soluzione in stile C potrebbe essere quella di utilizzare itoa, ma il modo migliore è stampare questo numero in una stringa utilizzando sprintf/snprintf . Controlla questa domanda: come convertire un numero intero in una stringa in modo portabile?

Notare che la itoafunzione non è definita in ANSI-C e non fa parte di C ++, ma è supportata da alcuni compilatori. È una funzione non standard, quindi dovresti evitare di usarla. Controlla anche questa domanda: alternativa a itoa () per convertire un intero in una stringa C ++?

Si noti inoltre che scrivere codice in stile C durante la programmazione in C ++ è considerato una cattiva pratica e talvolta indicato come "stile orribile". Vuoi davvero convertirlo in una char*stringa in C ? :)


5

Non scriverei via il const nell'ultima riga poiché è lì per un motivo. Se non puoi vivere con un const char *, è meglio che copi l'array di caratteri come:

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

vuoi dire che const char* char_type = temp_str.c_str();è meglio?
rsk82

1
Sì. c_str ti dà un puntatore al buffer interno dell'oggetto stringa. Se elimini const, tu o un altro programmatore potreste pensare che sia giusto cambiare il buffer tramite la variabile non const. Ma non è. L'oggetto stringa originale non sa nulla di queste modifiche. D'altra parte la stringa possiede ancora il buffer. Se l'oggetto stringa esce dall'ambito, la memoria dietro il puntatore viene eliminata dal distruttore degli oggetti stringa lasciandoti un puntatore penzolante. L'operazione di copia rimuove entrambi i problemi.
user331471

1
Alternativamente, std::vector<char> temp_vec(temp_str.begin(), temp_str.end()); temp_vec.push_back(0); char *char_type = &vec[0];. Questo ti dà una memoria mutevole, anche se ovviamente devi ancora mantenere in vita il vettore per tutto il tempo in cui vuoi usare il puntatore.
Steve Jessop

1
O semplicemente usa stringe non preoccuparti del vecchio, semplice, stupido char *dal vecchio, semplice C. <bit di fiamma destinati>
Griwes

@ Griwes: la domanda è come arrivarci char*, non "c'è qualche punto in cui chiamare da C ++ a librerie esistenti scritte in C, o dovrei reimplementarle in C ++?" ;-p
Steve Jessop

2

Va bene .. in primo luogo avevo bisogno di qualcosa che facesse quello che questa domanda sta chiedendo, ma ne avevo bisogno RAPIDAMENTE! Purtroppo il modo "migliore" è di quasi 600 righe di codice !!! Perdonate il nome che non ha niente a che fare con quello che sta facendo. Il nome proprio era Integer64ToCharArray (valore int64_t);

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

Sentiti libero di provare a ripulire quel codice senza ostacolare le prestazioni.

Ingresso: qualsiasi valore a 64 bit con segno da un intervallo minimo a un massimo.

Esempio:

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

Produzione:

Test: 9223372036854775807
Test: -9223372036854775808

Test di velocità originali: ( Integer64ToCharArray (); )

Miglior valore a 1 cifra.

Loop: 100.000.000, tempo impiegato: 1.381 (Milli), Time Per Loop 13 (Nano)

Caso peggiore Valore a 20 cifre.

Loop: 100.000.000, tempo speso: 22.656 (Milli), tempo per loop 226 (Nano

Nuovi test di velocità di progettazione: ( AddDynamicallyToBuffer (); )

Miglior valore a 1 cifra.

Loop: 100.000.000, tempo impiegato: 427 (Milli), Time Per Loop 4 (Nano)

Caso peggiore a 32 bit: valore a 11 cifre.

Loop: 100.000.000, tempo speso: 1.991 (Milli), Time Per Loop 19 (Nano)

Negativo 1 trilione di caso peggiore - Valore a 14 cifre.

Loop: 100.000.000, tempo impiegato: 5.681 (Milli), Time Per Loop 56 (Nano)

Caso peggiore a 64 bit: valore di 20 cifre.

Loop: 100.000.000, tempo impiegato: 13.148 (Milli), Time Per Loop 131 (Nano)

Come funziona!

Eseguiamo una tecnica di divisione e conquista e una volta raggiunta la lunghezza massima della stringa, impostiamo semplicemente ogni valore di carattere individualmente. Come mostrato nei test di velocità sopra, le lunghezze maggiori ottengono grosse penalità in termini di prestazioni, ma è ancora molto più veloce del metodo loop originale e nessun codice è effettivamente cambiato tra i due metodi, a parte il looping non è più in uso.

Nel mio utilizzo da qui il nome restituisco invece l'offset e non modifico un buffer di array di caratteri piuttosto comincio ad aggiornare i dati dei vertici e la funzione ha un parametro aggiuntivo per l'offset quindi non è inizializzata a -1.




0

Puoi anche usare il casting.

esempio:

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

1
E se il valore è negativo o non è una cifra?
Ziya ERKOC
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.