Ben dönüştürmek çalışıyorum std::stringiçin float/double. Denedim:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
Ama her zaman sıfır döndürür. Başka yol var mı?
Ben dönüştürmek çalışıyorum std::stringiçin float/double. Denedim:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
Ama her zaman sıfır döndürür. Başka yol var mı?
Yanıtlar:
std::string num = "0.6";
double temp = ::atof(num.c_str());
Benim için öyle mi, bir dizeyi ikiliye dönüştürmek geçerli bir C ++ sözdizimi.
Bunu stringstream veya boost :: lexical_cast ile yapabilirsiniz, ancak bunlar bir performans cezası ile gelir.
Ahaha bir Qt projeniz var ...
QString winOpacity("0.6");
double temp = winOpacity.toDouble();
Ek not:
Giriş verileri a ise const char*, QByteArray::toDoubledaha hızlı olacaktır.
Standart Kitaplık (C ++ 11) aşağıdakilerle istenen işlevselliği sunar std::stod:
std::string s = "0.6"
std::wstring ws = "0.7"
double d = std::stod(s);
double dw = std::stod(ws);
Genellikle diğer temel türlerin çoğu için bkz <string>. C dizgileri için de bazı yeni özellikler var. Görmek<stdlib.h>
ostringstreamkendi başına yazmak için çok uzundu, bırakın kullanmayı bırakın ..
Sözcüksel döküm çok güzel.
#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 )istisnayı yakalamak için kullanın .
Std :: stringstream'i kullanabilirsiniz:
#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;
}
Kullanım:
double number= StringToNumber<double>("0.6");
Arttırılmış sözcüksel döküm kullanabilirsiniz:
#include <boost/lexical_cast.hpp>
string v("0.6");
double dd = boost::lexical_cast<double>(v);
cout << dd << endl;
Not: boost :: lexical_cast istisna atar, bu nedenle geçersiz bir değer ilettiğinizde bununla başa çıkmaya hazır olmalısınız, dizeyi ("xxx") geçirmeyi deneyin
Eğer boost tümünde drag istemiyorsanız, gitmek strtod(3)dan <cstdlib>zaten bir çift döner -.
#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;
}
Çıktılar:
$ g++ -o s s.cc
$ ./s
0.6 0.6
$
Atof () neden çalışmıyor ... hangi platformda / derleyicide bulunuyorsunuz?
Bu cevap, yorumlarınızda litb'yi yedeklemektedir. Sonucu düzgün bir şekilde göstermediğiniz konusunda derin şüphelerim var.
Bir keresinde bana da aynı şey olmuştu. Tüm günümü 64 bitlik bir int'e neden kötü bir değer aldığımı anlamaya çalışarak geçirdim, sadece printf'in ikinci baytı görmezden geldiğini keşfetmek için. 64 bitlik bir değeri printf'e bir int gibi geçiremezsiniz.
atof()Asıl soruda neden işe yaramadığına gelince : ikiye katlanmış olması beni şüphelendiriyor. Kod olmadan derlenmemelidir #include <stdlib.h>, ancak dönüştürme bir derleme uyarısını çözmek için eklendiyse, atof()doğru şekilde bildirilmez. Derleyici talip olursa atof()döndürür bir int, bu dönüşüm uyarısı çözecek döküm, ancak olacak değil dönüş değeri bir çift olarak tanınmak neden olur.
#include <stdlib.h>
#include <string>
...
std::string num = "0.6";
double temp = atof(num.c_str());
uyarı olmadan çalışmalıdır.
Aksine denkleme Boost sürükleyerek yerine, bir gibi dize (geçici olarak) tutmak char[]ve kullanım sprintf().
Ancak elbette Boost kullanıyorsanız, bu gerçekten çok fazla bir sorun değil.
Yine de string <-> kayan nokta için lexical_cast istemezsiniz. Bu kullanım durumları alt kümesi, sürekli olarak artırmanın eski işlevlerden daha kötü olduğu tek kümedir - ve temelde tüm başarısızlıklarını orada yoğunlaştırdılar, çünkü kendi performans sonuçları, bu tür dönüştürmeler için sscanf ve printf kullanmaktan 20-25X DAHA YAVAŞ bir performans gösteriyor.
Kendin Google. boost :: lexical_cast, 50 dönüşüm gibi bir şeyi işleyebilir ve kayan nokta #s içerenleri hariç tutarsanız, bariz alternatifler kadar iyi veya daha iyidir (tüm bu işlemler için tek bir API'ye sahip olmanın ek avantajı ile). Ancak, performans açısından bir buzdağına çarpan şamandıralar ve benzerlerini getirin.
Eski, adanmış str-> double işlevlerinin tümü, 30 ms (veya daha iyi) gibi bir şeyde 10000 ayrıştırma yapabilir. lexical_cast aynı işi yapmak için 650 ms gibi bir şey alır.
Benim sorunum:
Çözümüm (Windows işlevi _wcstod_l kullanır):
// 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 ... bu çözüme ulaşmam oldukça uzun sürdü. Ve hala dizi yerelleştirmesi ve benzeri şeyler hakkında yeterince bilgim olmadığını hissediyorum ...