std::string zum Gleiten oder Verdoppeln

Lesezeit: 4 Minuten

Benutzer-Avatar
Max Frai

Ich versuche zu konvertieren std::string zu float/double. Ich habe es versucht:

std::string num = "0.6";
double temp = (double)atof(num.c_str());

Aber es gibt immer Null zurück. Irgendwelche anderen Möglichkeiten?

  • Widerstehen Sie dem Drang, etwas zu überarbeiten, das bereits vor einem Jahrzehnt herausgefunden wurde.

    – Emvee

    18. Juni 2009 um 13:28 Uhr

  • bist du sicher, dass du es richtig ausgibst? Es sollte nicht null ergeben

    – Johannes Schaub – litb

    18. Juni 2009 um 13:29 Uhr

  • außerdem musst du atof nicht wirken, es gibt bereits ein Pasch zurück.

    – AlbertoPL

    18. Juni 2009 um 13:34 Uhr

  • Ich bin sicher. Debugger zeigt mir 0. Und das Ergebnis ist 0. Plattform: Linux.

    – Max Frai

    18. Juni 2009 um 13:36 Uhr

  • Sind Sie sicher, dass Sie das richtige Gebietsschema installiert haben? versuchen Sie “0,6” oder setlocale(LC_NUMERIC, “C”);

    – Johannes Schaub – litb

    18. Juni 2009 um 13:37 Uhr

Benutzer-Avatar
TimW

std::string num = "0.6";
double temp = ::atof(num.c_str());

Für mich ist es eine gültige C++-Syntax, um eine Zeichenfolge in ein Double zu konvertieren.

Sie können dies mit stringstream oder boost::lexical_cast tun, aber diese sind mit Leistungseinbußen verbunden.


Ahaha, du hast ein Qt-Projekt …

QString winOpacity("0.6");
double temp = winOpacity.toDouble();

Zusätzliche Anmerkung:
Wenn die Eingabedaten a const char*, QByteArray::toDouble wird schneller sein.

  • boost::lexical_cast streamt.

    – TimW

    18. Juni 2009 um 13:40 Uhr

  • Man kann nicht allgemein sagen, dass sie mit einer Leistungsstrafe verbunden sind, denke ich. Denken Sie darüber nach, was passiert, wenn Sie kurz davor ein cin >> num; haben. Der Benutzer müsste sehr schnell tippen (rly jon skeet like), um jemals zu bemerken, dass lexical_cast in Millisekunden langsamer ist 🙂 Allerdings glaube ich, dass es Aufgaben gibt, bei denen lexical_cast einfach zu viel Leistung saugt 🙂

    – Johannes Schaub – litb

    18. Juni 2009 um 13:42 Uhr

  • Was macht für diese Lösung das :: vor atof()? Was muss da sein?

    – Shivabudh

    17. Februar 2010 um 2:04 Uhr

  • @ShaChris Weil ich sicherstellen möchte, dass ich die atof-Funktion aus dem globalen Namespace verwende.

    – TimW

    17. Februar 2010 um 8:16 Uhr

  • hängt vom aktuellen Gebietsschema ab

    – nmr

    20. Januar 2017 um 21:49 Uhr

Benutzer-Avatar
ManuelSchneid3r

Die Standard Library (C++11) bietet die gewünschte Funktionalität mit an std::stod :

std::string  s  = "0.6"
std::wstring ws = "0.7"
double d  = std::stod(s);
double dw = std::stod(ws);

Im Allgemeinen für die meisten anderen Grundtypen siehe <string>. Auch für C-Saiten gibt es einige Neuerungen. Sehen <stdlib.h>

  • Ich mag diese Lösung, aber es scheint, dass sie nur von C ++ 11 stammt. Also nicht auf meinem SDK verfügbar.

    – pamplemousse_mk2

    4. März 2013 um 10:45 Uhr

  • Es ist Großartig wissen, dass das C++ Standards Committee dies hinzugefügt hat. ostringstream an sich war einfach zu lang um es abzutippen, geschweige denn zu benutzen..

    – bobobobo

    23. Januar 2014 um 17:41 Uhr

  • Für Floats (wie in der Frage gestellt, die ich bei Google durch Eingabe von “c++ string to float” gefunden habe) sollte man std::stof verwenden.

    – Etienne

    25. Juli 2014 um 8:04 Uhr


  • Nur eine Anmerkung, dass dies Ausnahmen auslösen kann: std::invalid_argument (wenn die Konvertierung fehlgeschlagen ist) std::out_of_range (wenn außerhalb des Bereichs)

    – Jason Doucette

    12. Februar 2015 um 23:21 Uhr


  • Käufer aufgepasst, hängt vom aktuellen Gebietsschema ab.

    – nmr

    20. Januar 2017 um 21:46 Uhr

Die lexikalische Besetzung ist sehr schön.

#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;
}

  • Danke, es funktioniert.. Aber es ist eine Frage für mich: Warum mein Code nicht funktioniert.

    – Max Frai

    18. Juni 2009 um 13:55 Uhr

  • @Johannes Schaub: Basierend auf ADL könnte er genauso gut haben, dass die Verwendung von Definitionen und das, was er tatsächlich verwendet, wahrscheinlich eine große Anzahl von Std-Elementen in den Geltungsbereich bringen wird. Außerdem ist lexical_cast wahnsinnig langsam, also keine +1 von mir.

    Matthias N.

    10. März 2011 um 17:15 Uhr

  • Ein nettes Feature von boost::lexical_cast ist die Fehlerbehandlung. Wenn eine Konvertierung fehlschlägt, wird eine Ausnahme ausgelöst: try { ... boost::lexical_cast ... } catch (std::exception const& err) { //handle excpetion }

    – Semjon Mössinger

    9. Mai 2016 um 13:50 Uhr


  • Genauer gesagt verwenden catch ( boost::bad_lexical_cast const& err ) um die Ausnahme abzufangen.

    – Semjon Mössinger

    9. Mai 2016 um 14:56 Uhr

Benutzer-Avatar
Edison Gustavo Münz

Sie können std::stringstream verwenden:

   #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;
   }

Verwendungszweck:

double number= StringToNumber<double>("0.6");

Benutzer-Avatar
DaClown

Ja, mit lexikalischer Besetzung. Verwenden Sie einen Stringstream und den <<-Operator oder verwenden Sie Boost, sie haben es bereits implementiert.

Ihre eigene Version könnte so aussehen:

template<typename to, typename from>to lexical_cast(from const &x) {
  std::stringstream os;
  to ret;

  os << x;
  os >> ret;

  return ret;  
}

Benutzer-Avatar
stefanB

Sie können die lexikalische Umwandlung verstärken:

#include <boost/lexical_cast.hpp>

string v("0.6");
double dd = boost::lexical_cast<double>(v);
cout << dd << endl;

Hinweis: boost::lexical_cast löst eine Ausnahme aus, sodass Sie darauf vorbereitet sein sollten, damit umzugehen, wenn Sie einen ungültigen Wert übergeben. Versuchen Sie, string (“xxx”) zu übergeben.

Benutzer-Avatar
Bill Lynch

Wenn Sie nicht den gesamten Boost ziehen möchten, gehen Sie mit strtod(3) aus <cstdlib> – es gibt bereits ein Double zurück.

#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;
}

Ausgänge:

$ g++ -o s s.cc
$ ./s
0.6 0.6
$

Warum funktioniert atof() nicht … auf welcher Plattform/welchem ​​Compiler bist du?

  • Die Verwendung eines Stringstreams würde keinen Boost erfordern

    – jalf

    18. Juni 2009 um 13:29 Uhr

  • Ihre Methode gibt auch Null zurück. Linux.

    – Max Frai

    18. Juni 2009 um 13:31 Uhr

1013430cookie-checkstd::string zum Gleiten oder Verdoppeln

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy