Komma wird zu Punkt - aber wie wieder rückgängig?



  • Hallo,

    ich versuche damit

    for(string::iterator itStr = strLine.begin(); itStr != strLine.end(); itStr++)
    						if((*itStr) == ',') (*itStr = '.');
    

    die Kommas für die Berechnung durch Punkte zu ersetzen. Nun brauche ich sie aber wieder als Kommas am Ende bevor ich das ganze ich die Ausgabdatei packe. Wie bewerkstellige ich das? Bin ratlos!

    Vielen Dank für eure Hilfe im voraus.



  • Ich verstehe das Problem nicht. Du kannst ein Komma durch einen Punkt ersetzen, aber nicht umgekehrt 😕
    Wie wäre es, wenn Du einfach die Zeichen in der Schleife vertauschst?

    Übrigens geht es kürzer so:

    std::replace(strLine.begin(), strLine.end(), ',', '.');
    

    Der umgekehrte Weg ist gar nicht schwieriger.



  • TechM schrieb:

    ich versuche ... die Kommas für die Berechnung durch Punkte zu ersetzen. Nun brauche ich sie aber wieder als Kommas am Ende bevor ich das ganze ich die Ausgabdatei packe.

    Also Zahlen aus der Datei mit Kommas lesen und mit Komma statt Punkt wieder zurückschreiben.

    Das geht viel einfacher. Teile dem Stream aus dem Du liest doch einfach mit, dass Du 'deutsch' mit ihm reden willst. Im Deutschen ist das ',' der Dezimaltrenner. Etwa so

    #include <iostream>
    #include <fstream>
    #include <locale>
    
    int main ()
    {
        using namespace std;
        ifstream in("Datei.txt");
        in.imbue( locale( "german" ) ); // wir reden deutsch
        double z1, z2;
        in >> z1 >> z2; // z.B. 2 Zahlen lesen
        cout << "Gelesen: " << z1 << " " << z2 << endl;
    
        ofstream out("Datei2.txt");
        out.imbue( locale( "german" ) ); // scheiben auch in deutsch
        out << z1 << " " << z2 << endl;
        return 0;
    }
    

    Bem.: der String 'german' kann evt. auch anders heißen. Obiges funktioniert unter Windows.

    Gruß
    Werner



  • Da ist wohl jemandem langweilig -_-"



  • Hallo,

    also erstmal vielen Dank für eure Hilfe!

    das mit den locales wollte ich umgehen aber wie ich sehe wird es mit denen wohl um einiges einfacher sein.

    Hier mal der gesamte Quelltest da ich auf ein neues Problem gestoßen bin durch eben diese Änderung.

    #include <fstream>
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <cmath>
    #include <locale>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
        string strFileIn, strFileOut;
        string strLine, strTest;
        double d1, d2, d3, d4, d5, d6, dOut, dQuo, c0 = 11926.309;
    	char t1[30], t2[30];
        int iLineCount = 0, iBlockCount = 0, iArt;
    	bool ist = false;
    	long int lx, lstep = 1, ls = 0, lq = 100000000;
    
    	cout << "\t\t\t********** XXX v1.1 **********" << endl << endl;
    
    	//argumente prüfen
        if (argc < 3)
        {
            //keine oder zuwenig Parameter angegeben -> nach den Dateinamen fragen
            cout << "Eingabedatei angeben: ";
            cin >> strFileIn;
            cout << endl;
            cout << "Ausgabedatei angeben: ";
            cin >> strFileOut;
            cout << endl;
        }
        else
        {
            //Dateinamen aus Parameter-Array übernehmen
            strFileIn = argv[1];
            strFileOut = argv[2];
        }
    
    	//Wahl der Auswertungsart
    	cout << "Fuer logarithmische Auswertung waehlen Sie bitte die '1'" << endl;
    	cout << "Fuer lineare        Auswertung waehlen Sie bitte die '2'" << endl;
    	cout << "--> ";
    	cin >> iArt;
    	cout << endl;
    
    	if (iArt == 2)
    	{
    		//a einlesen
    		cout << "Beginn der Auswertung bei Lastwechsel ('0' eingeben fuer komplette Auswertung)" << endl;
    		cout << "--> ";
    		cin >> ls;
    		cout << endl;
    		//Ist ds ungleich '0' wird b eingelesen, ansonsten gilt der bei der Deklartion festgelegte Wert
    		if (ls != 0)
    		{
    			cout << "Ende der Auswertung bei Lastwechsel:" << endl;
    			cout << "--> ";
    			cin >> lq;
    			cout << endl;
    		}
    
    		//Schrittweite einlesen
    		cout << "Bitte Schrittweite eingeben:" << endl;
    		cout << "--> ";
    		cin >> lstep;
    		cout << endl;
    	}
    
    	//Dateien öffnen
    	ifstream in(strFileIn.c_str());			
        in.imbue( locale( "german" ) ); // wir reden deutsch
    	if(!in) return -2;
    
        ofstream out(strFileOut.c_str());
        out.imbue( locale( "german" ) ); // scheiben auch in deutsch
    	if(!out) return -3;
    
        //Datei lesen
        do
        {
            //Zeile einlesen
            getline(in, strLine);
            //alles OK?
            if(in)
            {
                //alles OK, kein Fehler aufgetreten und Datei noch nicht zu Ende
                //string in stringstream kopieren
                stringstream in(strLine);
                in >> strTest;
                //Wenn das 1. Wort 'Zyklische' ist, Zeilenzähler zurücksetzen und Blockzähler erhöhen
                if(strTest == "Zyklische")
                {
                    iLineCount = 0;
                    iBlockCount++;
                }
    
    			if (iBlockCount == 1 && iLineCount == 1)
    			{
    				out << "Anzahl der Lastwechsel" << ";" << "c [N/mm]" << ";" << "c/c0" << endl;
    			}
    
                //Zeile zählen
                iLineCount++;
                //Wenn Zeile leer ist, nichts machen
                if(strLine.empty())
                    continue;
    
    			if(iLineCount == 2 && iBlockCount > 0)
                {
                    //für 2. Zeile
                    //string in stringstream kopieren
                    stringstream in(strLine);
    				//Zeichenketten aus stringstream auslesen
                    in >> t1 >> t2 >> lx;
                }
    
    			if (iArt == 1)
    			{
    				if (lx > 0 && lx < 1000)
    					lstep = 100;
    				if (lx > 1000 && lx < 10000)
    					lstep = 1000;
    				if (lx > 10000 && lx < 100000)
    					lstep = 10000;
    				if (lx > 100000 && lx < 1000000)
    					lstep = 100000;
    				if (lx > 1000000 && lx < 10000000)
    					lstep = 1000000;
    			}
    
    			if (lx % lstep == 0)
    				ist = true;
    			else
    				ist = false;
    
                if (lx > (ls - 1) && lx < (lq + 1) && ist == true)
    			{
    
    				if(iLineCount == 6 && iBlockCount > 0)
    				{
    					//für 6. Zeile
    					//string in stringstream kopieren
    					stringstream in(strLine);
    					//Zahlen aus stringstream auslesen
    					in >> d1 >> d2 >> d3;
    				}
    
    				if(iLineCount == 7 && iBlockCount > 0)
    				{
    					//ab 7. Zeile
    					//string in stringstream kopieren
    					stringstream in(strLine);
    					//Zahlen aus stringstream auslesen
    					in >> d4 >> d5 >> d6;
    					//Berechnung durchführen
    					dOut = ((d6 + fabs(d3)) / (fabs(d2) + d5));
    					dQuo = (dOut / c0);
    					//Genauigkeit der Ausgabe setzen
    					out.precision(10);
    					//Ergebnis ausgeben
    					out << lx << ";" << dOut << ";" << dQuo << endl;
    				}
    			}
    
            }
        //bis Dateiende oder Fehler
        }while(in);
    
      	return 0;
    }
    

    Ich versuche folgende Text-datei mit diesem programm zu bearbeiten und in eine .csv-datei zu schreiben.

    Hier ein Auschnitt:
    es handelt sich hier um die 6. und 7. Zeile.
    6. Zeile: d1 d2 d3
    7. Zeile: d4 d5 d6

    10,550537 -0,093262166 -2803,3469
    10,588135 0,11793396 -284,5567

    wenn ich die nun einlesen kommen totaler Quatsch raus! Hab ich irgendwo einen Fehler?

    Ohne der Umstellung auf "german" lacale funktionierte es wunderbar!

    Kann mir jemand helfen?

    Danke im voraus!

    TechM



  • Hallo TechM,

    das Problem ist offensichtlich; weil die locale("german") gar nicht zum Lesen der Fließkommazahlen genutzt wird! In Zeile 73 setzt Du die locale("german") bei dem File. Aus diesem liest Du aber keine Zahlen sondern den Text in Zeile 84. Den Text steckst Du in einen stringstream (Zeile 145 und 154) und aus diesen liest Du dann die Fließkommazahlen aus. Der stringstream weiß nix von 'german' und versucht die Zahlen mit der Standard-Facette std::num_get zu lesen; und diese erwartet einen '.' als Dezimaltrenner.

    Kopiere die Zeile 73 hinter die Zeilen 145 und 154. Dann sollte es gehen.

    Es wäre außerdem hilfreich, direkt das einzulesen, was Du lesen willst und und die Schleife nur über die Blöcke laufen lässt. Das vereinfacht alles. Ich habe mir das etwa so vorgestellt.

    #include <fstream>
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <cmath>
    #include <locale>
    
    using namespace std;
    
    int getStep( int lx )
    {
        int lstep = 1;
        if (lx > 0 && lx < 1000)
            lstep = 100;
        if (lx > 1000 && lx < 10000)  // was, wenn lx == 1000 ?
            lstep = 1000;
        if (lx > 10000 && lx < 100000)
            lstep = 10000;
        if (lx > 100000 && lx < 1000000)
            lstep = 100000;
        if (lx > 1000000 && lx < 10000000)
            lstep = 1000000;
        return lstep;
    }
    
    int main(int argc, char* argv[])
    {
        string strFileIn, strFileOut;
        double c0 = 11926.309;
        int iArt;
        long lx = 1000000, lstep = 1, ls = 0, lq = 100000000;
    
        cout << "\t\t\t********** XXX v1.1 **********" << endl << endl;
    
        //argumente prüfen
        if (argc < 3)
        {
            //keine oder zuwenig Parameter angegeben -> nach den Dateinamen fragen
            cout << "Eingabedatei angeben: ";
            cin >> strFileIn;
            cout << endl;
            cout << "Ausgabedatei angeben: ";
            cin >> strFileOut;
            cout << endl;
        }
        else
        {
            //Dateinamen aus Parameter-Array übernehmen
            strFileIn = argv[1];
            strFileOut = argv[2];
        }
    
        //Wahl der Auswertungsart
        cout << "Fuer logarithmische Auswertung waehlen Sie bitte die '1'" << endl;
        cout << "Fuer lineare        Auswertung waehlen Sie bitte die '2'" << endl;
        cout << "--> ";
        cin >> iArt;
        cout << endl;
    
        if (iArt == 2)
        {
            //a einlesen
            cout << "Beginn der Auswertung bei Lastwechsel ('0' eingeben fuer komplette Auswertung)" << endl;
            cout << "--> ";
            cin >> ls;
            cout << endl;
            //Ist ds ungleich '0' wird b eingelesen, ansonsten gilt der bei der Deklartion festgelegte Wert
            if (ls != 0)
            {
                cout << "Ende der Auswertung bei Lastwechsel:" << endl;
                cout << "--> ";
                cin >> lq;
                cout << endl;
            }
    
            //Schrittweite einlesen
            cout << "Bitte Schrittweite eingeben:" << endl;
            cout << "--> ";
            cin >> lstep;
            cout << endl;
        }
    
        //Dateien öffnen
        ifstream in(strFileIn.c_str());           
        in.imbue( locale( "german" ) ); // wir reden deutsch
        if(!in) return -2;
    
        ofstream out(strFileOut.c_str());
        out.imbue( locale( "german" ) ); // scheiben auch in deutsch
        if(!out) return -3;
    
        out << "Anzahl der Lastwechsel" << ";" << "c [N/mm]" << ";" << "c/c0" << endl;
        for( string text1; in >> text1;  )
        {
            in.ignore( 999, '\n' );         // 1.Zeile Rest lesen
            if( text1 != "Zyklische" )
                continue;
            // --   Block lesen
            string dummy;
            in >> dummy >> dummy >> lx;
            in.ignore( 999, '\n' );         // 2.Zeile Rest lesen
            if( iArt == 1 ) lstep = getStep( lx );    
            if (lx >= ls  &&  lx <= lq  && (lx % lstep == 0) )
            {
                for( int zeilen = 3; zeilen; --zeilen )
                    in.ignore( 999, '\n' ); // 3.-5. Zeile
                double dummy, d2, d3, d5, d6;
                in >> dummy >> d2 >> d3;
                in.ignore( 999, '\n' );     // 6.Zeile (ignore evt. weglassen)
                in >> dummy >> d5 >> d6;    // 7.Zeile
    
                // -- Ergebnis ausgeben
                double dOut = ((d6 + fabs(d3)) / (fabs(d2) + d5));
                double dQuo = (dOut / c0);
                //Genauigkeit der Ausgabe setzen
                out.precision(10);
                //Ergebnis ausgeben
                out << lx << ";" << dOut << ";" << dQuo << endl;
            }
        }
        return 0;
    }
    

    Das ignore für die 6.Zeile hinter 'Zyklische' brauchst Du auch nur dann, wenn hinter den Zahlen noch was steht. Sonst könntest Du diese auch mit

    in >> dummy >> d2 >> d3 >> dummy >> d5 >> d6;
    

    einlesen. Der Zeilenumbruch stört nicht weiter.

    Gruß
    Werner



  • Hallo,

    also erstmal vielen vielen Dank für die Hilfe!

    Ich hatte es zwar in den Griff bekommen (wenn auch sehr tölpelhaft) aber deine Version ist um einiges besser.

    Es läuft jetzt auch schneller. Hatte nämlich bei manchen Datensätzen (so um die 16MB)schon mal 30 Sekunden gedauert. Jetzt ist es in 10 Sekunden durch.

    Viele Grüße

    TechM


Anmelden zum Antworten