Saya mencoba untuk beralih std::stringke float/double. Saya mencoba:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
Tapi selalu mengembalikan nol. Ada cara lain?
Saya mencoba untuk beralih std::stringke float/double. Saya mencoba:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
Tapi selalu mengembalikan nol. Ada cara lain?
Jawaban:
std::string num = "0.6";
double temp = ::atof(num.c_str());
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 ...
QString winOpacity("0.6");
double temp = winOpacity.toDouble();
Catatan tambahan:
Jika data masukan adalah const char*, QByteArray::toDoubleakan lebih cepat.
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>
ostringstreamitu sendiri terlalu panjang untuk diketik, apalagi digunakan ..
Pemeran leksikal sangat bagus.
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
using std::endl;
using std::cout;
using std::string;
using boost::lexical_cast;
int main() {
string str = "0.6";
double dub = lexical_cast<double>(str);
cout << dub << endl;
}
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:
#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;
}
Pemakaian:
double number= StringToNumber<double>("0.6");
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;
}
Anda dapat menggunakan boost lexical cast:
#include <boost/lexical_cast.hpp>
string v("0.6");
double dd = boost::lexical_cast<double>(v);
cout << dd << endl;
Catatan: boost :: lexical_cast melempar pengecualian jadi Anda harus siap menghadapinya ketika Anda memberikan nilai yang tidak valid, coba berikan string ("xxx")
Jika Anda tidak ingin tarik di semua dorongan, pergi dengan strtod(3)dari <cstdlib>- sudah mengembalikan ganda.
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;
int main() {
std::string num = "0.6";
double temp = ::strtod(num.c_str(), 0);
cout << num << " " << temp << endl;
return 0;
}
Keluaran:
$ g++ -o s s.cc
$ ./s
0.6 0.6
$
Mengapa atof () tidak berfungsi ... Anda menggunakan platform / kompiler apa?
double myAtof ( string &num){
double tmp;
sscanf ( num.c_str(), "%lf" , &tmp);
return tmp;
}
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.
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());
harus bekerja tanpa peringatan.
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.
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.
Masalahku:
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 detection
wchar_t* stopString;
// Create a locale for "C". Thus a '.' is expected as decimal separator
double 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 ...