Alternativa a itoa () per convertire un intero in stringa C ++?

Mi chiedevo se esistesse un’alternativa a itoa() per convertire un intero in una stringa perché quando lo itoa() in Visual Studio ricevo degli avvertimenti e quando provo a creare il mio programma sotto Linux, ottengo un errore di compilazione.

In C ++ 11 puoi usare std::to_string :

 #include  std::string s = std::to_string(5); 

Se stai lavorando prima del C ++ 11, potresti usare gli stream C ++:

 #include  int i = 5; std::string s; std::stringstream out; out << i; s = out.str(); 

Tratto da http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/

boost :: lexical_cast funziona abbastanza bene.

 #include  int main(int argc, char** argv) { std::string foo = boost::lexical_cast(argc); } 

Archeologia

itoa era una funzione di supporto non standard progettata per integrare la funzione standard di atoi, e probabilmente nascondeva uno sprintf (la maggior parte delle sue caratteristiche possono essere implementate in termini di sprintf): http://www.cplusplus.com/reference/clibrary/cstdlib/ itoa.html

La Via C

Usa sprintf. O snprintf. O qualunque strumento tu trovi.

Nonostante alcune funzioni non siano nello standard, come giustamente menzionato da “onebyone” in uno dei suoi commenti, la maggior parte del compilatore offrirà un’alternativa (ad esempio Visual C ++ ha il proprio _snprintf che può essere digitato a snprintf se ne hai bisogno).

Il modo in C ++.

Usa gli stream C ++ (nel caso corrente std :: stringstream (o anche il deprecato std :: strstream, come proposto da Herb Sutter in uno dei suoi libri, perché è un po ‘più veloce).

Conclusione

Sei in C ++, il che significa che puoi scegliere il modo in cui lo vuoi:

  • Il modo più veloce (vale a dire il modo C), ma dovresti assicurarti che il codice sia un collo di bottiglia nell’applicazione (le ottimizzazioni premature sono malvagie, ecc.) E che il codice sia incapsulato in modo sicuro per evitare il rischio di sovraccarichi del buffer.

  • Il modo più sicuro (ad esempio, il modo C ++), se sai che questa parte del codice non è critica, quindi meglio essere sicuri che questa parte del codice non si rompa in momentjs casuali perché qualcuno scambia una dimensione o un puntatore (che accade nella vita reale, come … ieri, sul mio computer, perché qualcuno ha pensato che fosse “bello” usare il modo più veloce senza realmente averlo bisogno).

Prova sprintf ():

 char str[12]; int num = 3; sprintf(str, "%d", num); // str now contains "3" 

sprintf () è come printf () ma restituisce una stringa.

Inoltre, come Parappa ha menzionato nei commenti, potresti voler usare snprintf () per impedire che si verifichi un overflow del buffer (dove il numero che stai convertendo non si adatta alle dimensioni della tua stringa.) Funziona così:

 snprintf(str, sizeof(str), "%d", num); 

Dietro le quinte, lexical_cast fa questo:

 std::stringstream str; str << myint; std::string result; str >> result; 

Se non vuoi “trascinare” la spinta per questo, allora usare quanto sopra è una buona soluzione.

Possiamo definire la nostra funzione iota in c ++ come:

 string itoa(int a) { string ss=""; //create empty string while(a) { int x=a%10; a/=10; char i='0'; i=i+x; ss=i+ss; //append new character at the front of the string! } return ss; } 

Non dimenticare di #include .

С ++ 11 risolve finalmente questo fornendo std::to_string . Anche boost::lexical_cast è uno strumento utile per i compilatori più vecchi.

Ecco una versione C di itoa, con alcune condizioni:

 char* custom_itoa(int i) { static char output[24]; // 64-bit MAX_INT is 20 digits char* p = &output[23]; for(*p--=0;i;i/=10) *p--=i%10+0x30; return ++p; } 
  • Questo non gestisce i numeri negativi
  • Questo al momento non gestisce numeri superiori a 23 caratteri in forma decimale.
  • non è thread-safe
  • il valore restituito verrà cancellato / danneggiato non appena la funzione viene richiamata di nuovo.
    Quindi se hai intenzione di mantenere il valore restituito, devi strcpy in un buffer separato.

Io uso questi modelli

 template  string toStr(T tmp) { ostringstream out; out << tmp; return out.str(); } template  T strTo(string tmp) { T output; istringstream in(tmp); in >> output; return output; } 

Prova Boost.Format o FastFormat , entrambe le librerie C ++ di alta qualità:

 int i = 10; std::string result; 

Con Boost.Format

 result = str(boost::format("%1%", i)); 

o FastFormat

 fastformat::fmt(result, "{0}", i); fastformat::write(result, i); 

Ovviamente entrambi fanno molto più di una semplice conversione di un singolo intero

In realtà puoi convertire qualsiasi cosa in una stringa con una funzione template abilmente scritta. Questo esempio di codice utilizza un ciclo per creare sottodirectory in un sistema Win-32. L’operatore di concatenazione di stringhe, operatore +, viene utilizzato per concatenare una radice con un suffisso per generare nomi di directory. Il suffisso viene creato convertendo la variabile di controllo del ciclo, i, in una stringa C ++, utilizzando la funzione template e concatenandola con un’altra stringa.

 //Mark Renslow, Globe University, Minnesota School of Business, Utah Career College //C++ instructor and Network Dean of Information Technology #include  #include  #include  #include  // string stream #include  using namespace std; string intToString(int x) { /**************************************/ /* This function is similar to itoa() */ /* "integer to alpha", a non-standard */ /* C language function. It takes an */ /* integer as input and as output, */ /* returns a C++ string. */ /* itoa() returned a C-string (null- */ /* terminated) */ /* This function is not needed because*/ /* the following template function */ /* does it all */ /**************************************/ string r; stringstream s; s << x; r = s.str(); return r; } template  string toString( T argument) { /**************************************/ /* This template shows the power of */ /* C++ templates. This function will */ /* convert anything to a string! */ /* Precondition: */ /* operator<< is defined for type T */ /**************************************/ string r; stringstream s; s << argument; r = s.str(); return r; } int main( ) { string s; cout << "What directory would you like me to make?"; cin >> s; try { mkdir(s.c_str()); } catch (exception& e) { cerr << e.what( ) << endl; } chdir(s.c_str()); //Using a loop and string concatenation to make several sub-directories for(int i = 0; i < 10; i++) { s = "Dir_"; s = s + toString(i); mkdir(s.c_str()); } system("PAUSE"); return EXIT_SUCCESS; } 

Assegna una stringa di lunghezza sufficiente, quindi usa snprintf.

La migliore risposta, IMO, è la funzione fornita qui:

http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

Mima la funzione non ANSI fornita da molte librerie.

 char* itoa(int value, char* result, int base); 

È anche fulmineo e ottimizza bene sotto -O3, e il motivo per cui non stai usando c ++ string_format () … o sprintf è che sono troppo lenti, giusto?

Si noti che tutti i metodi stringstream possono comportare il blocco attorno all’utilizzo dell’object locale per la formattazione. Potrebbe essere qualcosa di cui diffidare se stai utilizzando questa conversione da più thread …

Vedi qui per altro Converti un numero in una stringa con una lunghezza specificata in C ++

 int number = 123; stringstream = s; s << number; cout << ss.str() << endl; 

Se sei interessato al metodo di conversione delle stringhe intero veloce e sicuro e non limitato alla libreria standard, posso consigliare il metodo FormatInt dalla libreria di formato C ++ :

 fmt::FormatInt(42).str(); // convert to std::string fmt::FormatInt(42).c_str(); // convert and get as a C string // (mind the lifetime, same as std::string::c_str()) 

In base al numero intero di benchmark per la conversione delle stringhe di Boost Karma, questo metodo è molto più veloce rispetto a sprintf o std::stringstream . È persino più veloce del proprio int_generator di Boost Karma, come confermato da un benchmark indipendente .

Disclaimer: sono l’autore di questa libreria.

Ho scritto questa funzione thread-safe qualche tempo fa, e sono molto soddisfatto dei risultati e ritengo che l’algoritmo sia leggero e snello, con prestazioni che sono circa 3 volte la funzione standard MSQC _itoa ().

Ecco il link. Ottimale Base-10 solo funzione itoa ()? Le prestazioni sono almeno 10 volte quelle di sprintf (). Il benchmark è anche il test QA della funzione, come segue.

 start = clock(); for (int i = LONG_MIN; i < LONG_MAX; i++) { if (i != atoi(_i32toa(buff, (int32_t)i))) { printf("\nError for %i", i); } if (!i) printf("\nAt zero"); } printf("\nElapsed time was %f milliseconds", (double)clock() - (double)(start)); 

Ci sono alcuni suggerimenti sciocchi sull'utilizzo della memoria del chiamante che lascerebbe il risultato fluttuare da qualche parte in un buffer nello spazio degli indirizzi del chiamante. Ignorali. Il codice che ho elencato funziona perfettamente, come dimostra il codice di riferimento / QA.

Credo che questo codice sia abbastanza snello da poter essere utilizzato in un ambiente embedded. YMMV, ovviamente.

Sulle piattaforms derivate da Windows CE, non ci sono iostream s per impostazione predefinita. La strada da percorrere è preferibile con la famiglia _itoa<> , di solito _itow<> (poiché la maggior parte delle cose su stringhe sono comunque in Unicode).

La maggior parte dei suggerimenti sopra riportati tecnicamente non sono C ++, sono soluzioni C.

Guarda l’uso di std :: stringstream .