Anda tidak bisa secara umum mengatakan mereka datang dengan penalti kinerja, saya kira. Pikirkan tentang apa yang terjadi jika sebelum itu Anda memiliki cin >> num ;. Pengguna harus mengetik dengan sangat cepat (rly jon skeet like) untuk mencatat milidetik lexical_cast lebih lambat :) Yang mengatakan, saya percaya ada tugas di mana lexical_cast hanya menyebalkan terlalu banyak kinerja :)
Johannes Schaub - litb
3
Untuk solusi ini, apa yang dilakukan :: di depan atof ()? Apa yang dibutuhkan untuk berada di sana?
sivabudh
4
@ShaChris Karena saya ingin memastikan saya menggunakan fungsi atof dari namespace global.
TimW
1
tergantung pada lokasi saat ini
nmr
104
Pustaka Standar (C ++ 11) menawarkan fungsionalitas yang diinginkan dengan std::stod:
std::string s ="0.6"
std::wstring ws ="0.7"double d = std::stod(s);double dw = std::stod(ws);
Umumnya untuk kebanyakan tipe dasar lainnya, lihat <string>. Ada beberapa fitur baru untuk string C juga. Lihat<stdlib.h>
Saya suka solusi ini, tetapi tampaknya hanya dari C ++ 11. Jadi tidak tersedia di SDK saya.
pamplemousse_mk2
Ini bagus untuk mengetahui bahwa panitia C ++ standar menambahkan ini. ostringstreamitu sendiri terlalu panjang untuk diketik, apalagi digunakan ..
bobobobo
4
Untuk float (seperti yang ditanyakan dalam pertanyaan yang saya temukan dengan google dengan mengetik "c ++ string to float"), seseorang harus menggunakan std :: stof.
Étienne
1
Hanya catatan bahwa ini dapat memunculkan pengecualian: std :: invalid_argument (jika konversi gagal) std :: out_of_range (jika di luar kisaran)
Jason Doucette
3
Pembeli berhati-hatilah, tergantung pada lokal saat ini.
Terima kasih, berhasil .. Tapi ini pertanyaan bagi saya: mengapa kode saya tidak berfungsi.
Max Frai
2
@Johannes Schaub: Berdasarkan ADL, dia mungkin juga memiliki, definisi yang menggunakan ditambah apa yang sebenarnya dia gunakan mungkin akan membawa ke ruang lingkup sejumlah besar elemen std. Selain itu lexical_cast sangat lambat, jadi tidak ada +1 dari saya.
Fitur yang bagus dari boost :: lexical_cast adalah penanganan kesalahan. Jika konversi gagal, pengecualian dilemparkan:try { ... boost::lexical_cast ... } catch (std::exception const& err) { //handle excpetion }
Semjon Mössinger
Untuk lebih tepatnya, gunakan catch ( boost::bad_lexical_cast const& err )untuk menangkap pengecualian.
Semjon Mössinger
14
Anda dapat menggunakan std :: stringstream:
#include<sstream>#include<string>template<typename T>
T StringToNumber(const std::string& numberAsString){
T valor;
std::stringstream stream(numberAsString);
stream >> valor;if(stream.fail()){
std::runtime_error e(numberAsString);throw e;}return valor;}
Uhm, jadi menurutmu boost :: lexical_cast memiliki antarmuka yang buruk, bukan? Lihat jawaban StefanB! Boost melakukan hal yang sama.
kirsche40
@ kirsche40 Sepertinya alternatif yang baik untuk orang-orang yang belum memiliki ketergantungan dengan Boost (menghubungkan dengan Boost hanya untuk mengonversi std :: string ke angka agak berlebihan!)
Jean-Philippe Jodoin
@ JEan-Phillippe Jodiun Saya menjawab komentar yang sekarang dihapus, di mana seseorang merekomendasikan Boost. Saya sadar bahwa Boost sering kali berlebihan. Ngomong-ngomong, untuk beberapa waktu sekarang penggunaan Boost dibatasi untuk kompiler "lebih baru". Proyek lama tidak dapat menggunakan Boost. Misalnya ASIO sangat bergantung pada fitur-fitur C ++ 11 seperti std :: addressof yang membuatnya benar-benar tidak berguna untuk kompiler C ++ 98 / C ++ 03. IMHO, ketika proyek dimulai, Boost bermaksud untuk menyediakan fitur "standar" baru untuk versi kompilator yang lebih lama ... :-(
kirsche40
10
Ya, dengan pemeran leksikal. Gunakan stringstream dan operator <<, atau gunakan Boost, mereka sudah menerapkannya.
Versi Anda sendiri akan terlihat seperti ini:
template<typename to,typename from>to lexical_cast(from const&x){
std::stringstream os;
to ret;
os << x;
os >> ret;return ret;}
Catatan: boost :: lexical_cast melempar pengecualian jadi Anda harus siap menghadapinya ketika Anda memberikan nilai yang tidak valid, coba berikan string ("xxx")
Jawaban tidak valid, bagaimana Anda tahu bahwa nilai yang disimpan dalam bilangan sebenarnya adalah bilangan floating point yang valid? Anda tidak memeriksa kembali jenis sscanf, sepertinya gaya pengkodean MS.
1
Jawaban ini mendukung komentar Anda. Saya sangat curiga Anda tidak menampilkan hasilnya dengan benar.
Aku pernah mengalami hal yang persis sama padaku. Saya menghabiskan sepanjang hari mencoba mencari tahu mengapa saya mendapatkan nilai buruk menjadi int 64-bit, hanya untuk menemukan bahwa printf mengabaikan byte kedua. Anda tidak bisa begitu saja memberikan nilai 64-bit ke printf seperti int.
Saya tidak menggunakan printf untuk melihat hasil ... Dan saya menggunakan nilai itu untuk mengatur opasitas jendela, dan jendela saya transparan penuh, jadi nilainya 0.
Max Frai
1
Cara C ++ 11 adalah dengan menggunakan std :: stod dan std :: to_string. Keduanya bekerja di Visual Studio 11.
Mengapa atof() tidak berfungsi dalam pertanyaan asli: fakta bahwa itu dilemparkan menjadi dua kali lipat membuat saya curiga. Kode tidak boleh dikompilasi tanpa #include <stdlib.h>, tetapi jika pemeran ditambahkan untuk menyelesaikan peringatan kompilasi, maka atof()tidak dideklarasikan dengan benar. Jika compiler mengasumsikan atof()kembali int, casting itu akan memecahkan peringatan konversi, tetapi akan tidak menyebabkan nilai kembali untuk diakui sebagai ganda.
#include<stdlib.h>#include<string>...
std::string num ="0.6";double temp = atof(num.c_str());
Anda tidak ingin Boost lexical_cast untuk string <-> floating point. Subset kasus penggunaan tersebut adalah satu-satunya rangkaian yang peningkatannya secara konsisten lebih buruk daripada fungsi yang lebih lama - dan pada dasarnya semua kegagalannya terkonsentrasi di sana, karena hasil performa mereka sendiri menunjukkan performa 20-25X lebih lambat daripada menggunakan sscanf dan printf untuk konversi semacam itu.
Google sendiri. boost :: lexical_cast dapat menangani sesuatu seperti 50 konversi dan jika Anda mengecualikan yang melibatkan floating point #s itu sama baiknya atau lebih baik dengan alternatif yang jelas (dengan keuntungan tambahan memiliki satu API untuk semua operasi tersebut). Tapi bawa pelampung dan itu seperti Titanic menabrak gunung es dalam hal kinerja.
Fungsi str-> double yang lama dan berdedikasi semuanya dapat melakukan 10.000 parsing dalam waktu seperti 30 ms (atau lebih baik). lexical_cast membutuhkan waktu seperti 650 ms untuk melakukan pekerjaan yang sama.
String independen lokal menjadi ganda (pemisah desimal selalu '.')
Deteksi kesalahan jika konversi string gagal
Solusi saya (menggunakan fungsi Windows _wcstod_l):
// string to convert. Note: decimal seperator is ',' here
std::wstring str = L"1,101";// Use this for error detectionwchar_t* stopString;// Create a locale for "C". Thus a '.' is expected as decimal separatordouble dbl = _wcstod_l(str.c_str(),&stopString, _create_locale(LC_ALL,"C"));if(wcslen(stopString)!=0){// ... error handling ... we'll run into this because of the separator}
HTH ... butuh waktu lama bagi saya untuk mendapatkan solusi ini. Dan saya masih merasa bahwa saya tidak cukup tahu tentang lokalisasi string dan semacamnya ...
Jawaban:
Apakah itu untuk saya, itu adalah sintaks C ++ yang valid untuk mengubah string menjadi ganda.
Anda dapat melakukannya dengan stringstream atau boost :: lexical_cast tetapi hal itu disertai dengan penalti kinerja.
Ahaha Anda memiliki proyek Qt ...
Catatan tambahan:
Jika data masukan adalah
const char*
,QByteArray::toDouble
akan lebih cepat.sumber
Pustaka Standar (C ++ 11) menawarkan fungsionalitas yang diinginkan dengan
std::stod
:Umumnya untuk kebanyakan tipe dasar lainnya, lihat
<string>
. Ada beberapa fitur baru untuk string C juga. Lihat<stdlib.h>
sumber
ostringstream
itu sendiri terlalu panjang untuk diketik, apalagi digunakan ..Pemeran leksikal sangat bagus.
sumber
try { ... boost::lexical_cast ... } catch (std::exception const& err) { //handle excpetion }
catch ( boost::bad_lexical_cast const& err )
untuk menangkap pengecualian.Anda dapat menggunakan std :: stringstream:
Pemakaian:
sumber
Ya, dengan pemeran leksikal. Gunakan stringstream dan operator <<, atau gunakan Boost, mereka sudah menerapkannya.
Versi Anda sendiri akan terlihat seperti ini:
sumber
Anda dapat menggunakan boost lexical cast:
Catatan: boost :: lexical_cast melempar pengecualian jadi Anda harus siap menghadapinya ketika Anda memberikan nilai yang tidak valid, coba berikan string ("xxx")
sumber
Jika Anda tidak ingin tarik di semua dorongan, pergi dengan
strtod(3)
dari<cstdlib>
- sudah mengembalikan ganda.Keluaran:
Mengapa atof () tidak berfungsi ... Anda menggunakan platform / kompiler apa?
sumber
Saya memiliki masalah yang sama di Linux
berhasil.
sumber
sumber
Jawaban ini mendukung komentar Anda. Saya sangat curiga Anda tidak menampilkan hasilnya dengan benar.
Aku pernah mengalami hal yang persis sama padaku. Saya menghabiskan sepanjang hari mencoba mencari tahu mengapa saya mendapatkan nilai buruk menjadi int 64-bit, hanya untuk menemukan bahwa printf mengabaikan byte kedua. Anda tidak bisa begitu saja memberikan nilai 64-bit ke printf seperti int.
sumber
Cara C ++ 11 adalah dengan menggunakan std :: stod dan std :: to_string. Keduanya bekerja di Visual Studio 11.
sumber
Mengapa
atof()
tidak berfungsi dalam pertanyaan asli: fakta bahwa itu dilemparkan menjadi dua kali lipat membuat saya curiga. Kode tidak boleh dikompilasi tanpa#include <stdlib.h>
, tetapi jika pemeran ditambahkan untuk menyelesaikan peringatan kompilasi, makaatof()
tidak dideklarasikan dengan benar. Jika compiler mengasumsikanatof()
kembali int, casting itu akan memecahkan peringatan konversi, tetapi akan tidak menyebabkan nilai kembali untuk diakui sebagai ganda.harus bekerja tanpa peringatan.
sumber
Daripada menyeret Boost ke dalam persamaan, Anda dapat menyimpan string (sementara) sebagai
char[]
dan digunakansprintf()
.Tetapi tentu saja jika Anda tetap menggunakan Boost, itu sebenarnya tidak terlalu menjadi masalah.
sumber
Anda tidak ingin Boost lexical_cast untuk string <-> floating point. Subset kasus penggunaan tersebut adalah satu-satunya rangkaian yang peningkatannya secara konsisten lebih buruk daripada fungsi yang lebih lama - dan pada dasarnya semua kegagalannya terkonsentrasi di sana, karena hasil performa mereka sendiri menunjukkan performa 20-25X lebih lambat daripada menggunakan sscanf dan printf untuk konversi semacam itu.
Google sendiri. boost :: lexical_cast dapat menangani sesuatu seperti 50 konversi dan jika Anda mengecualikan yang melibatkan floating point #s itu sama baiknya atau lebih baik dengan alternatif yang jelas (dengan keuntungan tambahan memiliki satu API untuk semua operasi tersebut). Tapi bawa pelampung dan itu seperti Titanic menabrak gunung es dalam hal kinerja.
Fungsi str-> double yang lama dan berdedikasi semuanya dapat melakukan 10.000 parsing dalam waktu seperti 30 ms (atau lebih baik). lexical_cast membutuhkan waktu seperti 650 ms untuk melakukan pekerjaan yang sama.
sumber
Masalahku:
Solusi saya (menggunakan fungsi Windows _wcstod_l):
HTH ... butuh waktu lama bagi saya untuk mendapatkan solusi ini. Dan saya masih merasa bahwa saya tidak cukup tahu tentang lokalisasi string dan semacamnya ...
sumber