Scientific Notation für String der gespeichert wird



  • Hallo zusammen,

    ich bin gerade dabei die Erstellung einer Analyse Datei in mein Projekt einzubinden. D.h. in meinen Klassen gibt es eine Funktion summary(), die einen String zurückgibt und dieser dann gespeichert wird. Das sieht wie folgt aus:

    void AFC::MixtureFraction::summary() const
    {
         //- Open file for writing 
        std::fstream file;
    
        file.open("analyze", std::fstream::out);
    
        file<< Header();
    
        file<< chemistry_.summary();
        file<< thermo_.summary();
        file<< transport_.summary();
        file<< gasKinetics_.summary();
    
        file.close();
    }
    

    Soweit funktioniert das auch. Allerdings sind einige Zahlen mit e^45 usw. definiert. In meiner Analyse Datei sieht das dann wie folgt aus:

    Reaction 3:  H+O2(+M)=HO2(+M)
       =============================================
    
          A:  5580000000000.000000
          n:  0.400000
          Ea: 0.000000 cal/mol
    
         LOW Coeffs (for high pressure)
    
             A:  840000000000000000.000000 
             n:  -0.800000
             Ea: 0.000000 cal/mol
    
         TROE Coeffs
    
            a:  0.500000
            b:  0.000000
            c:  1000000000000000019884624838656.000000
            d:  0.000000
    
       Reaction 4:  OH+HO2=H2O+O2
       =============================================
    
          A:  50000000000000.000000
          n:  0.000000
          Ea: 1000.000000 cal/mol
    
       Reaction 5:  H+HO2=OH+OH
       =============================================
    
          A:  250000000000000.000000
          n:  0.000000
          Ea: 1900.000000 cal/mol
    

    Ich möchte in meiner Datei jedoch die wissenschaftliche Notation (scientific). Wenn ich die Zahlen über std::cout<< std::scientific plotte, dann erhalte ich das gewünschte Ergebnis, jedoch weiß ich nicht wie ich ein double in ein scientific string umwandele, da ich in den Funktionen summary() alles in einen String packe und diesen als Rückgabe Parameter habe. Um einen kurzen Einblick zu geben, hier ein kurzer Ausschnitt aus der summary() Funktion:

    if(chemData_.TROE(r))
                {
                    tmp += "     TROE Coeffs\n\n";
    
                    const List<scalar>& TROECoeffs = chemData_.TROECoeffs(r);
                    tmp += "        a:  " + toStr(TROECoeffs[0]) + "\n";
                    tmp += "        b:  " + toStr(TROECoeffs[1]) + "\n";
                    tmp += "        c:  " + toStr(TROECoeffs[2]) + "\n";
                    tmp += "        d:  " + toStr(TROECoeffs[3]) + "\n";
                }
    

    Das Problem (so scheint es mir) ist die Umwandlung von double in das string Format. toStr ist std::to_string.

    Hab schon ein paar sachen probiert aber bislang noch keine positiven Resultate gefunden, außer das es wohl an dieser Umwandlung liegt.

    Danke fürs durchlesen,
    Grüße Tobi



  • Wenn ich dich richtig verstanden habe, suchst du std::stringstream . In deinen summary()-Funktionen packst du alles da rein, wie wenn du es mit std::cout machen würdest und gibst schlussendlich mittels std::stringstream::str() einen String zurück.


  • Mod

    Vielleicht wäre es allgemein eine bessere Idee, eine Ausgabefunktion zu schreiben, die einen ostream als Parameter hat und alles wie gewünscht in diesen schreibt, anstatt den Umweg zu gehen, einen String zu erstellen, weiter zu reichen und letztlich doch nur in einen ostream zu schreiben. Als Namen für diese Ausgabefunktion schlage ich operator<< vor.



  • Hey Sepp,

    danke für die Antwort. Das werde ich mir mal anschauen und sicher auch so umsetzen. Wie du schon erwähnt hast, ist das wesentlich besser wie die Sache die ich mach.

    Danke für den Denkanstoß!

    Grüße Tobi



  • Hallo zusammen,

    ich wollte hier nur noch meine Lösung posten. Wie Sepp bereits erwähnte, habe ich die Funktionen (summary()) nun so abgeändert, dass diese einen ostream aufnimmt und ich in diesen alles speichere:

    std::filebuf file;
        file.open("analyze", std::ios::out);
    
        //- Ostream that take the information
        std::ostream data(&file);
    
        //- Set scientific notation and precision to floatfield
        data.setf(std::ios::scientific, std::ios::floatfield);
    
        //- Header
        data<< Header() << "\n";
    
        //- Build the chemistry summary
        chemistry_.summary(data);
    
        //- Build the thermodynamic summary
        thermo_.summary(data);
    
        file.close();
    

    Funktionier einwandfrei und ich hab meine scientific notation mit flaot Genauigkeit. Wollte die Genauigkeit auf 4 Nachkommastellen begrenzen aber das wollte nicht. Folgendes hab ich versucht:

    data.precision(4);
    

    Die Info hab ich aus dieser Tabelle: http://www.cplusplus.com/reference/ostream/ostream/?kw=ostream und sollte auf die nächste Zahl angewendet werden. Will nur leider nicht so, aber das ist jetzt auch kein rießiges Problem.

    Danke Sepp für den Hinweis mit dem Ostream.


Anmelden zum Antworten