Come faccio a convertire un doppio in una stringa in C ++?


171

Devo memorizzare un doppio come stringa. So che posso usarlo printfse volessi visualizzarlo, ma voglio solo memorizzarlo in una variabile stringa in modo da poterlo archiviare in una mappa in un secondo momento (come valore , non come chiave ).


2
Una domanda per rispondere alla tua domanda: perché stai memorizzando il doppio valore in una stringa per memorizzarlo in una mappa? Utilizzerai il doppio ified di stringa come chiave? In caso contrario, perché non lasciare il doppio così com'è?
Matt McClellan,

1
Punto interessante L'uso di un doppio come chiave di una mappa può essere pieno di pericoli, tuttavia, come sempre sono i confronti esatti su valori in virgola mobile. L'indicizzazione su una rappresentazione di stringa evita il problema.
Fred Larson,

2
Perché convertirlo? Memorizzalo nella mappa come doppio ed evita la conversione da e verso.
EvilTeach del

3
Sembra ancora una richiesta di oggetti. Un'unione funzionerebbe. Ciascuno dell'oggetto per inserire vari valori al suo interno e averlo auto-validato.
EvilTeach

2
Ho solo un mucchio di coppie nome / valore in un file. Non richiede oggetti.
Bill the Lizard,

Risposte:


183

Il modo boost (tm) :

std::string str = boost::lexical_cast<std::string>(dbl);

Il modo C ++ standard :

std::ostringstream strs;
strs << dbl;
std::string str = strs.str();

Nota : non dimenticare#include <sstream>


3
Penso che boost :: lexical_cast È praticamente il modo standard C ++, semplicemente ben confezionato per te. A proposito, litb, hai un piccolo errore di battitura - "boot: lexical_cast".
Fred Larson,

2
boost :: lexical_cast non è solo un semplice wrapper attorno al codice stringstream. Molte delle routine di conversione sono implementate in linea. In base alle misurazioni delle prestazioni nella parte inferiore di questa pagina ( boost.org/doc/libs/1_47_0/libs/conversion/lexical_cast.htm ), boost :: lexical_cast è più veloce dell'uso di stringstreams e, nella maggior parte dei casi, più veloce di scanf / printf
Ferruccio,

1
@Ferr chi ha detto che era un semplice wrapper? E grazie per aver fornito il link, in realtà ho pensato che fosse più o meno un semplice wrapper :)
Johannes Schaub - litb

27
non dimenticare di farlo #include <sstream>per il modo c ++ :)
VladL

3
Per motivi di documentazione, in caso contrario #include <sstream>, verrà visualizzato un messaggio di errore "il tipo incompleto non è consentito".
Trevor Sullivan,

194
// The C way:
char buffer[32];
snprintf(buffer, sizeof(buffer), "%g", myDoubleVar);

// The C++03 way:
std::ostringstream sstream;
sstream << myDoubleVar;
std::string varAsString = sstream.str();

// The C++11 way:
std::string varAsString = std::to_string(myDoubleVar);

// The boost way:
std::string varAsString = boost::lexical_cast<std::string>(myDoubleVar);

1
Il tuo modo C ++ non funzionerà perché operator <<restituisce un std::ostream&anziché un stringstream&.
Konrad Rudolph,

Sembra che i miei archi siano un po 'arrugginiti, preferisco i vecchi modi. Risolto ora (spero).
Adam Rosenfield,

Il tuo codice C all'inizio mi ha buttato via. Ti ho ancora votato per aver dato alternative corrette.
Bill the Lizard,

2
voto per includere il modo C. mi sembra molto più pulito.
Nealon,

11
Eseguito l'upgrade per il modo C ++ 11. Sono nuovo di C ++ e non ho realizzato che esistesse una to_stringfunzione. Sto usando Microsoft Visual C ++ 2013.
Trevor Sullivan,

123

Il modo standard C ++ 11 (se non ti interessa il formato di output):

#include <string>

auto str = std::to_string(42.5); 

to_stringè una nuova funzione di libreria introdotta in N1803 (r0), N1982 (r1) e N2408 (r2) " Accesso numerico semplice ". Ci sono anche le stodfunzioni per eseguire l'operazione inversa.

Se si desidera avere un formato di output diverso rispetto a "%f", utilizzare i metodi snprintfo ostringstreamcome illustrato in altre risposte.


3
Oh si Tesoro. to_string e stod funzionano entrambi in Visual Studio 11.
BSalita

Oh caro bambino ... to_string non sembra funzionare in VisualStudio 2010): Quello o non so cosa sto facendo (molto possibile)
chessofnerd

1
Questo dovrebbe essere più alto, dal momento che è più moderno!
gsamaras,

1
Esiste un modo per rendere questa funzione non aggiungere più decimali del necessario? Quando converto il doppio 8.0mi dà la stringa "8.000000", mentre "8"andrebbe benissimo.
Ciao Arrivederci

1
Questo non funziona per piccoli numeri ... ad es .: 1e-9produce0.000000
user3728501

24

Se usi C ++, evita sprintf. È un-C ++ y e ha diversi problemi. Gli stringstreams sono il metodo di scelta, preferibilmente incapsulato come in Boost.LexicalCast che può essere fatto abbastanza facilmente:

template <typename T>
std::string to_string(T const& value) {
    stringstream sstr;
    sstr << value;
    return sstr.str();
}

Uso:

string s = to_string(42.5);

24

È possibile utilizzare std :: to_string in C ++ 11

double d = 3.0;
std::string str = std::to_string(d);

I miei numeri erano davvero piccoli, e std::to_string()semplicemente restituivano 0,000000 e non nella forma scientifica.
Erfan,

11

sprintfva bene, ma in C ++, il modo migliore, più sicuro e anche leggermente più lento di fare la conversione è con stringstream:

#include <sstream>
#include <string>

// In some function:
double d = 453.23;
std::ostringstream os;
os << d;
std::string str = os.str();

Puoi anche usare Boost.LexicalCast :

#include <boost/lexical_cast.hpp>
#include <string>

// In some function:
double d = 453.23;
std::string str = boost::lexical_cast<string>(d);

In entrambi i casi, strdovrebbe essere "453.23"dopo. LexicalCast presenta alcuni vantaggi in quanto garantisce che la trasformazione sia completa. Usa stringstreams internamente.


10

Vorrei esaminare la C ++ String Toolkit Libary . Ho appena pubblicato una risposta simile altrove. L'ho trovato molto veloce e affidabile.

#include <strtk.hpp>

double pi = M_PI;
std::string pi_as_string  = strtk::type_to_string<double>( pi );


6

Il problema con lexical_cast è l'incapacità di definire la precisione. Normalmente se stai convertendo un doppio in una stringa, è perché vuoi stamparlo. Se la precisione è troppo o troppo piccola, ciò influirebbe sulla tua produzione.



4

Heh, ho appena scritto questo (non correlato a questa domanda):

string temp = "";
stringstream outStream;
double ratio = (currentImage->width*1.0f)/currentImage->height;
outStream << " R: " << ratio;
temp = outStream.str();

/* rest of the code */


2

Dai un'occhiata sprintf()e famiglia.


2
Ho citato printf perché googling ha rivelato un mucchio di articoli che dicono di convertire da una doppia a una stringa che usi printf. Presumono che l'unica cosa che potresti fare sia la stampa, che nel mio caso è falsa.
Bill the Lizard,

perché voti -1? Penso che lo sprintf sia buono. @BilltheLizard, lo sprint stampa qualcosa sullo schermo di un carattere * non. Qualcuno ha risposto che il metodo c ha ottenuto ancora molti voti.
worldterminator,

2

Normalmente per queste operazioni devi usare le funzioni ecvt, fcvt o gcvt:

/* gcvt example */
#include <stdio.h>
#include <stdlib.h>

main ()
{
  char buffer [20];
  gcvt (1365.249,6,buffer);
  puts (buffer);
  gcvt (1365.249,3,buffer);
  puts (buffer);
  return 0;
}

Output:
1365.25
1.37e+003   

Come una funzione:

void double_to_char(double f,char * buffer){
  gcvt(f,10,buffer);
}

0

Potresti provare uno stile più compatto:

std::string number_in_string;

double number_in_double;

std::ostringstream output;

number_in_string = (dynamic_cast< std::ostringstream*>(&(output << number_in_double <<

std::endl)))->str(); 

0

Usa to_string().
esempio :

#include <iostream>   
#include <string>  

using namespace std;
int main ()
{
    string pi = "pi is " + to_string(3.1415926);
    cout<< "pi = "<< pi << endl;

  return 0;
}

eseguilo tu stesso: http://ideone.com/7ejfaU Anche
questi sono disponibili:

string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);

0

Puoi convertire qualsiasi cosa in qualsiasi cosa usando questa funzione:

template<class T = std::string, class U>
T to(U a) {
    std::stringstream ss;
    T ret;
    ss << a;
    ss >> ret;
    return ret;
};

utilizzo:

std::string str = to(2.5);
double d = to<double>("2.5");
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.