Domanda

    

Questa domanda ha già una risposta qui:

         

Mi chiedevo se ci fosse un'alternativa a itoa() per convertire un numero intero in una stringa perché quando lo eseguo in Visual Studio ricevo avvisi e quando provo a compilare il mio programma su Linux, ricevo un errore di compilazione .

È stato utile?

Soluzione

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

#include <string>

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

Se stai lavorando con prima di C ++ 11, puoi usare i flussi C ++:

#include <sstream>

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 /

Altri suggerimenti

boost :: lexical_cast funziona abbastanza bene.

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

Archeologia

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

The C Way

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 dei compilatori ti offrirà un'alternativa (ad esempio Visual C ++ ha il suo _snprintf che puoi digitaref per snprintf se ne hai bisogno).

Il modo C ++.

Usa gli stream C ++ (nel caso attuale std :: stringstream (o anche lo std :: strstream deprecato, 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 desideri:

  • Il modo più veloce (cioè il modo C), ma dovresti essere sicuro che il codice sia un collo di bottiglia nella tua applicazione (le ottimizzazioni premature sono malvagie, ecc.) e che il tuo codice sia incapsulato in modo sicuro per evitare il rischio di sovraccarichi del buffer .

  • Il modo più sicuro (cioè il modo C ++), se conosci questa parte del codice non è critica, quindi assicurati che questa parte del codice non si spezzi in momenti casuali perché qualcuno ha scambiato una dimensione o un puntatore (che succede nella vita reale, come ... ieri, sul mio computer, perché qualcuno l'ha pensato " cool " per usare il modo più veloce senza averne davvero 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 menzionato da Parappa nei commenti, potresti voler usare snprintf () per impedire che si verifichi un overflow del buffer (dove il numero che stai convertendo non si adatta alla dimensione 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 si desidera " trascinare " aumentare questo, quindi utilizzare quanto sopra è una buona soluzione.

Possiamo definire la nostra iota funzione 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 <string>.

& # 1057; ++ 11 risolve infine questo problema std::to_string . Inoltre boost::lexical_cast è uno strumento utile per compilatori meno recenti.

Uso questi modelli

template <typename T> string toStr(T tmp)
{
    ostringstream out;
    out << tmp;
    return out.str();
}


template <typename T> 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;

WIth Boost.Format

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

o FastFormat

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

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

Puoi effettivamente convertire qualsiasi cosa in una stringa con una funzione modello 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 <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // string stream
#include <direct.h>

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 <class T>
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

Imita la funzione non ANSI fornita da molte librerie.

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

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

Nota che tutti i stringstream metodi potrebbero comportare il blocco dell'uso dell'oggetto locale per la formattazione. Questo potrebbe essere qualcosa di cui diffidare se stai usando questa conversione da più thread ...

Vedi qui per ulteriori informazioni. Converti un numero in una stringa con la lunghezza specificata in C ++

int number = 123;

stringstream = s;

s << number;

cout << ss.str() << endl;

Se sei interessato a un metodo di conversione da intero a sicuro veloce e sicuro e non limitato alla libreria standard, posso consigliare il metodo FormatInt dal Formato C ++ libreria:

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())

Secondo i benchmark di conversione da intero a stringa da Boost Karma, questo metodo molte volte più veloce di sprintf o std::stringstream di glibc. È anche più veloce di quello di Boost Karma int_generator come è stato confermato da un benchmark indipendente .

Disclaimer: sono l'autore di questa libreria.

Ho scritto questa funzione thread-safe qualche tempo fa, e sono molto contento dei risultati e sento che l'algoritmo è leggero e snello, con prestazioni che sono circa 3 volte la funzione standard MSVC _itoa () .

Ecco il link. Optimal Base-10 solo funzione itoa ()? Le prestazioni sono almeno 10 volte quella 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 stupidi sull'utilizzo della memoria del chiamante che lascerebbe il risultato fluttuante da qualche parte in un buffer nello spazio degli indirizzi del chiamante. Ignorali. Il codice che ho elencato funziona perfettamente, come dimostra il codice benchmark / QA.

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

Sulle piattaforme derivate da Windows CE, per impostazione predefinita non ci sono iostream s. La strada da percorrere è preferibilmente con la famiglia _itoa<>, di solito _itow<> (dato che la maggior parte delle cose di stringa sono comunque Unicode lì).

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

Guarda in std :: stringstream .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top