Bagaimana cara mengkonversi ganda menjadi string di C ++?

171

Saya perlu menyimpan dobel sebagai string. Saya tahu saya dapat menggunakan printfjika saya ingin menampilkannya, tetapi saya hanya ingin menyimpannya dalam variabel string sehingga saya dapat menyimpannya di peta nanti (sebagai nilainya , bukan kunci ).

Bill the Lizard
sumber
2
Sebuah pertanyaan untuk menjawab pertanyaan Anda: mengapa Anda menyimpan nilai ganda dalam sebuah string untuk menyimpannya di peta? Apakah Anda akan menggunakan string-ified double sebagai kuncinya? Jika tidak, mengapa tidak meninggalkan dobel apa adanya?
Matt McClellan
1
Poin yang menarik. Menggunakan ganda sebagai kunci peta mungkin penuh dengan bahaya, namun, seperti perbandingan yang tepat pada nilai floating point selalu begitu. Pengindeksan pada representasi string menghindari masalah.
Fred Larson
2
Mengapa mengubahnya sama sekali? Simpan di peta sebagai dobel, dan hindari konversi ke dan dari.
EvilTeach
3
Itu masih terdengar seperti panggilan untuk objek. Serikat pekerja akan bekerja. Setiap objek untuk menyisipkan berbagai nilai ke dalamnya, dan memilikinya memvalidasi diri.
EvilTeach
2
Saya hanya memiliki banyak pasangan nama / nilai dalam sebuah file. Itu tidak membutuhkan benda.
Bill the Lizard

Jawaban:

183

Cara peningkatan (tm) :

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

Cara Standar C ++ :

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

Catatan : Jangan lupa#include <sstream>

Johannes Schaub - litb
sumber
3
Saya pikir meningkatkan :: lexical_cast cukup banyak adalah cara standar C ++, hanya dikemas dengan baik untuk Anda. BTW, litb, Anda memiliki kesalahan ketik kecil di sana - "boot: lexical_cast".
Fred Larson
2
boost :: lexical_cast bukan hanya pembungkus sederhana di sekitar kode stringstream. Banyak rutin konversi diimplementasikan secara inline. Menurut pengukuran kinerja di bagian bawah halaman ini ( boost.org/doc/libs/1_47_0/libs/conversion/lexical_cast.htm ), boost :: lexical_cast lebih cepat daripada menggunakan stringstreams dan, dalam banyak kasus, lebih cepat daripada scanf / printf
Ferruccio
1
@ Fer yang mengatakan itu bungkus sederhana? Dan terima kasih telah menyediakan tautannya, saya benar - benar berpikir itu kurang lebih adalah pembungkus sederhana :)
Johannes Schaub - litb
27
jangan lupa #include <sstream>untuk c ++ way :)
VladL
3
Demi dokumentasi, jika tidak #include <sstream>, Anda akan mendapatkan kesalahan "tipe tidak lengkap tidak diizinkan."
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);
Adam Rosenfield
sumber
1
Cara C ++ Anda tidak akan berfungsi karena operator <<mengembalikan a std::ostream&daripada a stringstream&.
Konrad Rudolph
Sepertinya stringstreams saya agak berkarat, saya lebih suka cara C '. Tetap sekarang (saya harap).
Adam Rosenfield
Kode C Anda melempar saya pada awalnya. Saya masih memilih Anda untuk memberikan alternatif yang benar.
Bill the Lizard
2
memilih untuk menyertakan cara C. sepertinya jauh lebih bersih bagi saya.
Nealon
11
Terpilih untuk cara C ++ 11. Saya baru mengenal C ++, dan tidak menyadari bahwa ada to_stringfungsi. Saya menggunakan Microsoft Visual C ++ 2013.
Trevor Sullivan
123

Cara Standard C ++ 11 (jika Anda tidak peduli dengan format output):

#include <string>

auto str = std::to_string(42.5); 

to_stringadalah fungsi perpustakaan baru yang diperkenalkan di N1803 (r0), N1982 (r1) dan N2408 (r2) " Simple Numeric Access ". Ada juga stodfungsi untuk melakukan operasi terbalik.

Jika Anda ingin memiliki format output yang berbeda dari "%f", gunakan metode snprintfatau ostringstreamseperti yang diilustrasikan dalam jawaban lain.

kennytm
sumber
3
Oh ya sayang. to_string dan stod keduanya bekerja di Visual Studio 11.
BSalita
Oh sayang sayang ... to_string tampaknya tidak berfungsi di VisualStudio 2010): Itu, atau saya tidak tahu apa yang saya lakukan (sangat mungkin)
chessofnerd
1
Ini harus lebih tinggi, karena lebih modern!
gsamaras
1
Apakah ada cara untuk membuat fungsi ini tidak menambahkan lebih banyak desimal dari yang dibutuhkan? Ketika saya mengkonversi ganda 8.0itu memberi saya string "8.000000", sementara "8"itu akan baik-baik saja.
HelloGoodbye
1
Ini tidak berfungsi untuk jumlah kecil ... misalnya: 1e-9menghasilkan0.000000
user3728501
24

Jika Anda menggunakan C ++, hindari sprintf. Ini un-C ++ y dan memiliki beberapa masalah. Stringstreams adalah metode pilihan, lebih disukai dienkapsulasi seperti pada Boost.LexicalCast yang dapat dilakukan dengan cukup mudah:

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

Pemakaian:

string s = to_string(42.5);
Konrad Rudolph
sumber
24

Anda dapat menggunakan std :: to_string di C ++ 11

double d = 3.0;
std::string str = std::to_string(d);
Yochai Timmer
sumber
Jumlah saya sangat kecil, dan std::to_string()hanya mengembalikan 0,000000 dan tidak dalam bentuk ilmiah.
erfan
11

sprintftidak apa-apa, tetapi dalam C ++, cara konversi yang lebih baik, lebih aman, dan juga sedikit lebih lambat adalah dengan stringstream:

#include <sstream>
#include <string>

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

Anda juga dapat menggunakan Boost.LexicalCast :

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

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

Dalam kedua kasus, strharus "453.23"sesudahnya. LexicalCast memiliki beberapa kelebihan karena memastikan transformasi selesai. Menggunakan stringstreams secara internal.

coppro
sumber
10

Saya akan melihat C + + String Toolkit Libary . Baru saja memposting jawaban yang serupa di tempat lain. Saya telah menemukannya sangat cepat dan dapat diandalkan.

#include <strtk.hpp>

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

Masalah dengan lexical_cast adalah ketidakmampuan untuk mendefinisikan presisi. Biasanya jika Anda mengonversi dobel menjadi string, itu karena Anda ingin mencetaknya. Jika presisi terlalu banyak atau terlalu sedikit, itu akan mempengaruhi output Anda.


sumber
4

Anda juga bisa menggunakan stringstream .

Firas Assaad
sumber
4

Heh, saya baru saja menulis ini (tidak terkait dengan pertanyaan ini):

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

/* rest of the code */
Vinko Vrsalovic
sumber
2

Anda mungkin ingin membaca posting saya sebelumnya di SO. (Versi makro dengan objek ostringstream sementara.)

Sebagai catatan: Dalam kode saya sendiri, saya mendukung snprintf (). Dengan array char pada stack lokal, itu tidak efisien. (Yah, mungkin jika Anda melebihi ukuran array dan mengulang untuk melakukannya dua kali ...)

(Saya juga sudah membungkusnya melalui vsnprintf (). Tapi itu perlu saya beberapa jenis pengecekan. Tolong kalau Anda mau kodenya ...)

Mr.Ree
sumber
2

Lihatlah sprintf()dan keluarga.

Darron
sumber
2
Saya menyebutkan printf karena googling menemukan banyak artikel yang mengatakan untuk mengkonversi dari double ke string yang Anda gunakan printf. Mereka membuat asumsi bahwa satu-satunya hal yang dapat Anda lakukan adalah mencetak, yang dalam kasus saya salah.
Bill the Lizard
mengapa Anda memilih -1? Saya pikir sprintf bagus. @BilltheLizard, sprint mencetak sesuatu ke layar char * not. Seseorang menjawab metode c masih mendapat banyak suara.
worldterminator
2

Untuk operasi ini, Anda harus menggunakan Fungsi ecvt, fcvt atau 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   

Sebagai fungsi:

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

Anda bisa mencoba gaya yang lebih ringkas:

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(); 
Alexis Sánchez Tello
sumber
0

Gunakan to_string().
contoh:

#include <iostream>   
#include <string>  

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

  return 0;
}

jalankan sendiri: http://ideone.com/7ejfaU
Ini juga tersedia:

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);
Rika
sumber
0

Anda dapat mengonversi apa pun menjadi apa pun menggunakan fungsi ini:

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

penggunaan:

std::string str = to(2.5);
double d = to<double>("2.5");
Sam Mokari
sumber