Bagaimana Anda mengonversi pelampung menjadi string di C ++ sambil menentukan presisi & jumlah digit desimal?
Sebagai contoh: 3.14159265359 -> "3.14"
c++
string
floating-point
Shannon Matthews
sumber
sumber
Jawaban:
Cara tipikal adalah dengan menggunakan
stringstream
:#include <iomanip> #include <sstream> double pi = 3.14159265359; std::stringstream stream; stream << std::fixed << std::setprecision(2) << pi; std::string s = stream.str();
Lihat diperbaiki
dan setprecision .
Untuk konversi tujuan teknis , seperti menyimpan data dalam file XML atau JSON, C ++ 17 mendefinisikan keluarga fungsi to_chars .
Dengan asumsi kompiler yang sesuai (yang tidak kami miliki pada saat penulisan), hal seperti ini dapat dipertimbangkan:
#include <array> #include <charconv> double pi = 3.14159265359; std::array<char, 128> buffer; auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), pi, std::chars_format::fixed, 2); if (ec == std::errc{}) { std::string s(buffer.data(), ptr); // .... } else { // error handling }
sumber
Metode umum untuk melakukan hal semacam ini adalah dengan "mencetak ke string". Dalam C ++ itu berarti menggunakan
std::stringstream
sesuatu seperti:std::stringstream ss; ss << std::fixed << std::setprecision(2) << number; std::string mystring = ss.str();
sumber
Pilihan lainnya adalah
snprintf
:double pi = 3.1415926; std::string s(16, '\0'); auto written = std::snprintf(&s[0], s.size(), "%.2f", pi); s.resize(written);
Demo . Penanganan kesalahan harus ditambahkan, yaitu memeriksa
written < 0
.sumber
snprintf
lebih baik dalam kasus ini? Tolong jelaskan ... Ini pasti tidak akan lebih cepat, menghasilkan lebih sedikit kode [Saya telah menulis implementasi printf, itu cukup kompak hanya di bawah 2000 baris kode, tetapi dengan ekspansi makro mencapai sekitar 2500 baris]__printf_fp
fungsionalitas dasar yang sama - agak aneh bahwa proses ini memakan waktu lebih lamastringstream
, karena seharusnya tidak perlu.Anda bisa menggunakan C ++ 20
std::format
ataufmt::format
fungsi dari pustaka {fmt} ,std::format
berdasarkan:#include <fmt/core.h> int main() std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14" }
dimana
2
presisi.sumber
Di sini solusi hanya menggunakan std. Namun, perhatikan bahwa ini hanya membulatkan ke bawah.
float number = 3.14159; std::string num_text = std::to_string(number); std::string rounded = num_text.substr(0, num_text.find(".")+3);
Untuk
rounded
itu menghasilkan:3.14
Kode tersebut mengubah seluruh float menjadi string, tetapi memotong semua karakter 2 karakter setelah "."
sumber
number + 0.005
dalam kasus saya.Di sini saya memberikan contoh negatif di mana Anda ingin menghindari saat mengubah bilangan mengambang menjadi string.
float num=99.463; float tmp1=round(num*1000); float tmp2=tmp1/1000; cout << tmp1 << " " << tmp2 << " " << to_string(tmp2) << endl;
Anda mendapatkan
99463 99.463 99.462997
Catatan: variabel num dapat berupa nilai apa pun yang mendekati 99,463, Anda akan mendapatkan hasil cetak yang sama. Intinya adalah untuk menghindari fungsi "to_string" c ++ 11 yang nyaman. Butuh beberapa saat untuk keluar dari jebakan ini. Cara terbaik adalah metode stringstream dan sprintf (bahasa C). C ++ 11 atau yang lebih baru harus memberikan parameter kedua sebagai jumlah digit setelah titik mengambang untuk ditampilkan. Saat ini defaultnya adalah 6. Saya mengemukakan hal ini agar orang lain tidak membuang waktu untuk masalah ini.
Saya menulis versi pertama saya, beri tahu saya jika Anda menemukan bug yang perlu diperbaiki. Anda dapat mengontrol perilaku persisnya dengan iomanipulator. Fungsi saya adalah untuk menunjukkan jumlah digit setelah koma desimal.
string ftos(float f, int nd) { ostringstream ostr; int tens = stoi("1" + string(nd, '0')); ostr << round(f*tens)/tens; return ostr.str(); }
sumber