float Zahlen aus einer txt auslesen und in array speichern



  • Hallo Leute,

    ich habe mich heute angemeldet weil ich gedacht hab etwas Hilfe von eurer Seite zu bekommen, bin noch relativ neu in C++ und habe ein Problem bei dem ich heute nach langer Suche nicht so richtig weiter gekommen bin.

    Und zwar es geht um folgendes:

    Ich habe eine .txt Datei, in welcher viele float Werte gespeichert, hier ein Beispiel:

    Stoff A:
    0.0092938484 0.0090909093094 -0.9900293E-10 9.99878747828 234.039984092
    9.0984838998 -9.09090949E-10 9.090909344332 0.09039043090 9.09039044E-7
    ... ... ... ... ...

    Stoff B: (sind andere Werten aber ich habs einfach copy-paste gemacht)
    0.0092938484 0.0090909093094 -0.9900293E-10 9.99878747828 234.039984092
    9.0984838998 -9.09090949E-10 9.090909344332 0.09039043090 9.09039044E-7
    ... ... ... ... ...

    Stoff C: (-""-)
    0.0092938484 0.0090909093094 -0.9900293E-10 9.99878747828 234.039984092
    9.0984838998 -9.09090949E-10 9.090909344332 0.09039043090 9.09039044E-7
    ... ... ... ... ...

    usw.

    so ich möchte jetzt folgendes programmieren:

    - es soll eine Eingabe durch den Benutzer erfolgen welchen Stoff er braucht
    - dann müsste die richtigen Zeilen gefunden werden
    - und jeder Werte in jeder Zeile sollte in ein Array gespeichert werden, so das man mit diesen Wert im späteren verlauf rechnen kann

    ich habs mir heute i.wie mit Strings und Chars zusammengebastelt aber so richtig von meinem Tun bin ich nicht überzeugt 🙂

    Hier der Code[C++]:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <sstream>

    using namespace std;

    int main()
    {
    fstream Datei;
    string such, eingabe;
    string a,b,c,d ;
    int n = 1;

    Datei.open("C:\\Users\\xxx\\Desktop\\master.txt");

    cout << "Eingabe:" << endl;
    cin >> eingabe;

    do
    {
    getline (Datei, such) ;
    n = n + 1 ;

    }while(such != eingabe) ;

    if (such == eingabe)
    {
    getline (Datei, a); // 1.Zeile unter dem H2O
    getline (Datei, b); // 2.Zeile unter dem H2O
    getline (Datei, c); // 3.Zeile unter dem H2O
    getline (Datei, d); // 4.Zeile unter dem H2O
    }
    else if (such != eingabe)
    {
    cout << n ;
    }

    const char* p = a.c_str();

    char string[]= p; // An dieser Stelle will ich mein p drinnen haben, aber leider funktioniert das nicht

    cout << "string[0]" << string[0] << endl;
    char delimiter[] = " ";
    char *ptr;

    double Feld[10];

    ptr = strtok(string, delimiter);

    stringstream stream;
    stream << ptr;
    double number;
    stream >> number;

    Feld[0]=number;

    for(int i=1; i<4; i++)
    {
    ptr = strtok(0, delimiter);

    stringstream stream;
    stream << ptr;
    double number;
    stream >> number;

    Feld[i] = number;
    }

    system ("pause");
    return 0;

    }

    Allgemein find ich das persönlich sehr kompliziert geschrieben, habt ihr vlt einen eleganteren Vorschlag oder kann man das so lassen ?

    Lg



  • Hallo ArtiTT,

    dein Quellcode schaut irgendwie zu verkopft aus. Ich würde da, vor allem als Anfänger, ganz logisch vorgehen. Angenommen, die Datei schaut wie folgt aus:

    Stoff A:
    0.1 0.2 0.3
    0.4 0.5 0.6
    
    Stoff B:
    1.1 1.2 1.3
    1.4 1.5 1.6
    
    Stoff C:
    2.1 2.2 2.3
    2.4 2.5 2.6
    

    Wie viele Werte zu einem Stoff gehören, spielt nachfolgend keine Rolle.

    Vorgehensweise:

    1. Du fragst dich, welche Datentypen du brauchst. Es kommen Zeichenketten und Kommawerte vor. Also nehmen wir std::string und float/double. Soweit hast du es ja schon richtig gemacht.

    2. Es wird von oben nach unten gelesen. Ich nehme an, A B und C sind hier Platzhalter für irgendwelche Namen. Demnach besteht jede Überschrift aus zwei Zeichenketten ( Stoff und A: ). Also müssen wir zuerst einmal zwei Zeichenketten einlesen.

    3. Nachdem wir die beiden Zeichenketten eingelesen haben, lesen wir Schritt für Schritt die nachfolgenden Kommawerte ein. Wir speichern einen eingelesen Wert, wenn die zweite Zeichenkette dem gesuchten Stoff entspricht. Ist das nicht der Fall, verwerfen wir die eingelesenen Wert einfach.

    4. Wie wissen wir, wann eine neue Überschrift kommt? Irgendwann wird versucht, in einem double eine Zeichenkette zu speichern. Das geht nicht. Diese Operation schlägt fehl und das Stream-Objekt geht in einen Fehlerzustand über. Das ist für uns der Hinweis, dass alle Kommawerte verarbeitet wurden und nun eventuell eine neue Überschrift folgt oder die Datei zu Ende ist. Wir müssen nun den Fehlerzustand beheben (clear) und dann kann das ganze Spiel von vorne losgehen.

    Quellcode:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    
    int main()
    {
    	std::string search;
    	std::cout << "Search: ";
    	std::cin >> search;
    
    	std::ifstream file("test.txt");
    	std::vector<double> values;
    
    	for(std::string material, x; file>>material>>x;) // 2.
    	{
    		for(double d; file>>d;) // 3.
    		{
    			if( x.find(search) != std::string::npos )
    				values.push_back(d);
    		}
    		file.clear(); // 4.
    	}
    }
    


  • Hey großen Dank für die schnelle Antwort und die ausführliche Erklärung.

    Ich hab da noch ein paar fragen, weil ich teilweise nicht weiß was die Befehle die da drinnen sind machen.

    Es ist eig. nur ein Stoffname da, also nur eine Zeichenkett, hab das soweit umgeändert.

    Was bedeutet den das vector<double> values, das string::npos und das values.push_back(d), und was genau nochmal das file.clear() ?

    Sowie ich das verstanden habe werden ja die Werte in d eingespeichert ? und ich hab da jetzt versucht sie in der Schleife einzuspeichern, aber i.wie speichert der alle Werte die in der txt.Datei vorhanden sind... habs bestimmt falsch gemacht. Tut mir leid, bin da noch nicht so in der Materie und lern noch 🙂

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>

    using namespace std;

    int main()
    {
    string search;
    cout << "Search: ";
    cin >> search;

    int i=0;
    double alpha[30];

    ifstream file("C:\\Users\...\\Desktop\\master.txt");
    vector<double> values;

    for(string material; file>>material;) // 2.
    {
    for(double d; file>>d;) // 3.
    {
    if( material.find(search) != string::npos )
    values.push_back(d);

    alpha[i] = d; ++i;
    }

    file.clear(); // 4.
    }

    system("pause");
    return 0;
    ]

    --------------------------------------------------------------------------------

    ich glaube, das file.clear(); müsste in der 2. for Schleife stehen oder ? weil das speichert er genau nur die Werte die zu dem Stoffname gehört 🙂



  • Es ist eig. nur ein Stoffname da, also nur eine Zeichenkett, hab das soweit umgeändert.

    Joa dann musst nur eine Zeichenkette einlesen.

    Was bedeutet den das vector<double> values
    

    Das ist ein dynamisches Array. D.h. die Größe des Arrays kann zur Laufzeit beliebig sein. Du hast ein statisches Array benutzt. Wenn es zu einem Stoff mal mehr als 30 Werte gibt, hast du ein Problem. Bei dynamischen Arrays hast du kein Problem.

    string::npos
    

    Das bedeutet "nicht gefunden".

    values.push_back(d)
    

    Das bedeutet, dass du eine Kopie der Variable d im Array values ablegst.

    und was genau nochmal das file.clear() ?
    

    Ein Stream-Objekt kann verschiedene Zustände annehmen: good, bad, fail, eof. Wenn das Stream-Objekt nicht im Zustand good ist, kannst du damit keine Streamoperationen durchführen. clear() versetzt das Stream-Objekt wieder in den Zustand good. Wie gesagt, es irgendwann wird versucht, eine Zeichenkette in einem double zu speichern. Das geht nicht und die Operation schlägt fehl und das Stream-Objekt geht in den Zustand fail über.

    Sowie ich das verstanden habe werden ja die Werte in d eingespeichert ?
    

    Ja, alle Werte werden in einer Variable double d gespeichert. Damit du die Werte nach der for-Schleife aber noch hast, musst du sie natürlich in ein Array kopieren.

    und ich hab da jetzt versucht sie in der Schleife einzuspeichern, aber i.wie speichert der alle Werte die in der txt.Datei vorhanden sind...
    

    Dein alpha[i] = d; ++i; steht nich innerhalb der if.

    ich glaube, das file.clear(); müsste in der 2. for Schleife stehen oder ?
    

    Ne. Der Fehlerzustand tritt ja bei einem Lesevorgang auf. Ein erfolgreicher Lesevorgang ist Bedingung für einen Schleifendurchlauf. Würde es in der for-Schleife stehen, würde der Fehlerzustand nicht beseitigt werden.



  • ArtiTT schrieb:

    Hallo Leute,

    ich habe mich heute angemeldet weil ich gedacht hab etwas Hilfe von eurer Seite zu bekommen,

    Hallo ArtiTT,

    Willkommen im C++-Forum.

    ArtiTT schrieb:

    Ich hab da noch ein paar fragen, weil ich teilweise nicht weiß was die Befehle die da drinnen sind machen.

    out hat Dir ja schon gut geholfen. Du kannst die einzelnen Methoden und Klassen des C++-Standards auch hier nachlesen. (vector, push_back, string::npos)
    Ansonsten ist ein gutes C++-Buch für Einsteiger zu empfehlen. Falls Du noch keins hast, so erkundige Dich vorher über die Qualität einzelner Bücher - am besten hier im Forum.

    ArtiTT schrieb:

    Es ist eig. nur ein Stoffname da, also nur eine Zeichenkett, hab das soweit umgeändert.

    Bei solchen Einlese-Problemen bitter immer eine Kopie eines Ausschnitts aus der Datei posten. Dann kann man Dir am besten helfen.

    Gruß
    Werner



  • Hey Out, danke nochmal, jetzt ergibt alles ein Sinn, eine Frage bleibt mir dennoch 🙂

    Und zwar, du hast ja gemeint, dass:

    vector<double> values
    

    ein dynamisches Array ist, heißt das das die Werte von

    double d
    

    hier abgelegt werden ? Und wenn ja wie kann ich diese dann wieder aufrufen ?

    Lg



  • Ah okay, hab es verstanden 🙂
    großes Dankeschön 🙂



  • ArtiTT schrieb:

    vector<double> values
    

    ein dynamisches Array ist, heißt das das die Werte von

    double d
    

    hier abgelegt werden ?

    Richtig.

    ArtiTT schrieb:

    Und wenn ja wie kann ich diese dann wieder aufrufen ?

    Ganz normal:

    cout << values[0];
    


  • Hey und zwar ich hab den Aufruf mit meiner richtigen txt. Datei probiert, leider klappt es da nicht, da teilweiße die Strings übereinstimmen,
    d.h. ich suche z.B. die Verbindung "abcde", es gibt aber auch eine Verbindung die mit der anderen im Sring übereinstimmt, also z.B. "abc". Aber ich brauche z.B. nur die Verbindung "abcde" und nicht beide, wie kann ich da unterscheiden?

    @ out: ich könnte dir auch die txt. Datei mal schicken i.wie da kannst das mal selber schauen wie das aufgebaut ist, weil ich glaub so ohne zu wissen wie die ganau ausschaut es schwer vorstellbar ist 🙂

    Noch eine andere Frage zu diesem Forum 🙂 wie füge ich den solche Programmcodestücke ein so wie du die immer machst ?

    lg 🙂

    P.S. Dankeschön schon mal 🙂



  • ArtiTT schrieb:

    @ out: ich könnte dir auch die txt. Datei mal schicken i.wie da kannst das mal selber schauen wie das aufgebaut ist, weil ich glaub so ohne zu wissen wie die ganau ausschaut es schwer vorstellbar ist 🙂

    Du kannst den Inhalt auch einfach mit copy&paste hier posten.

    ArtiTT schrieb:

    Noch eine andere Frage zu diesem Forum 🙂 wie füge ich den solche Programmcodestücke ein so wie du die immer machst ?

    Also ich klicke 2x auf den "C++"-Button und füge mein innerhalb der beiden Tags ein.



  • so schaut das aus, nur mit mehr Stoffen, und eig brauche ich immer nur die 2 und die 3 Zeile vom bestimmten Stoff, je nach Bedingungen welche gegeben sind, muss ich dann halt mit der 2. Zeile oder der 3. rechnen.

    SN                121286S   1N   1          G  0300.00   5000.00  1000.00      1
     3.88828659E+00 6.77842705E-04-2.72530883E-07 5.13592745E-11-3.59383628E-15    2
     3.04449609E+04 4.19429112E+00 3.40734577E+00 1.79788738E-03-2.01896978E-06    3
     2.10785744E-09-9.52759247E-13 3.06237324E+04 6.82148123E+00                   4
    SO                121286S   1O   1          G  0300.00   5000.00  1000.00      1
     4.02107763E+00 2.58485612E-04 8.94814178E-08-3.58014451E-11 3.22842987E-15    2
    -7.11962036E+02 3.45252252E+00 3.08040142E+00 1.80310570E-03 6.70502232E-07    3
    -2.06900541E-09 8.51465708E-13-3.98616303E+02 8.58102799E+00                   4
    SO2               121286S   1O   2          G  0300.00   5000.00  1000.00      1
     5.25449848E+00 1.97854545E-03-8.20422599E-07 1.57638291E-10-1.12045120E-14    2
    -3.75688555E+04-1.14605629E+00 2.91143870E+00 8.10302235E-03-6.90671004E-06    3
     3.32901551E-09-8.77712128E-13-3.68788164E+04 1.11174030E+01                   4
    SO3               121286S   1O   3          G  0300.00   5000.00  1000.00      1
     7.05066824E+00 3.24656023E-03-1.40889733E-06 2.72153494E-10-1.94236479E-14    2
    -5.02066758E+04-1.10644264E+01 2.57528257E+00 1.51509158E-02-1.22987167E-05    3
     4.24025703E-09-5.26681184E-13-4.89441055E+04 1.21951160E+01                   4
    

    und wenn ich jetzt z.B. SO brauche, und nach SO suche, dann greift er auch auf SO2 und auf SO3, bitte um Hilfe 🙂



  • ArtiTT schrieb:

    und wenn ich jetzt z.B. SO brauche, und nach SO suche, dann greift er auch auf SO2 und auf SO3, bitte um Hilfe 🙂

    Hallo ArtiII,

    Da kommt noch hinzu, dass hinter der Materialbezeichnung Dinge stehen, Du Du anscheinend nicht benötigst. Ändere das Programm von out wie folgt:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <limits> // std::numeric_limits< std::streamsize >
    
    int main()
    {
        std::string search;
        std::cout << "Search: ";
        std::cin >> search;
    
        std::ifstream file("C:\\Users\\...\\Desktop\\master.txt"); // <== Filename eintragen
        std::vector<double> values;
    
        for( std::string material; file >> material; ) // lese Wort für Wort
        {
            if( material == search ) // prüfe, ob das gelesene Wort 'material' mit 'search' über ein stimmt
                break; // gesuchtes Material gefunden; dann Suche abbrechen
        }
        file.ignore( std::numeric_limits< std::streamsize >::max(), '\n' ); // Rest der Zeile überlesen
        for(double d; file>>d;) // Werte einlesen; bis eine Fehler auftritt
        {
            values.push_back(d); // Werte in 'values' ablegen
        }
        std::cout << values.size() << " Werte gelesen" << std::endl;
    }
    

    Das 'numeric_limits< std::streamsize >::max()' in Zeile 21 steht hier für 'beliebig viele' - also heißt

    file.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );
    

    (über-)lese beliebig viele Zeichen bis Du ein '\n' (Zeilenende) gefunden wird.

    Da sollten immer 17 Werte gelesen werden. Ich unterstelle jedoch, dass Du die zahlen am Ende der Zeilen nicht benötigst - oder? Dieses stehen auch im vector 'values'.

    Gruß
    Werner



  • Hallo,

    ich stelle mir bezüglich dieses Threads 3 weitere Fragen:

    1.

    Ich besitze Messwerte, die ich mit dem Programm MATLAB aufnehmen werden. MIr ist noch nicht bekannt, wieviele das ingesamt werden. Die Messwerte werden in einer Matrix angelegt. Die Spaltenanzahl richtet sich nach einer Abtastrate und ist variabel.

    Die Zeilenanzahl richtet sich nach den Messzeiten und ist vom Benutzer einstellbar.

    Aufbauend auf:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <limits> // std::numeric_limits< std::streamsize >
    
    int main()
    {
        std::string search;
        std::cout << "Search: ";
        std::cin >> search;
    
        std::ifstream file("C:\\Users\\...\\Desktop\\master.txt"); // <== Filename eintragen
        std::vector<double> values;
    
        for( std::string material; file >> material; ) // lese Wort für Wort
        {
            if( material == search ) // prüfe, ob das gelesene Wort 'material' mit 'search' über ein stimmt
                break; // gesuchtes Material gefunden; dann Suche abbrechen
        }
        file.ignore( std::numeric_limits< std::streamsize >::max(), '\n' ); // Rest der Zeile überlesen
        for(double d; file>>d;) // Werte einlesen; bis eine Fehler auftritt
        {
            values.push_back(d); // Werte in 'values' ablegen
        }
        std::cout << values.size() << " Werte gelesen" << std::endl;
    }
    

    würde ich den code gerne verändern:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <limits> // std::numeric_limits< std::streamsize >
    
    int main()
    {
        std::string verzeichnis;
        std::cout << "Dateiverzeichnis: ";
        std::cin >> verzeichnis; 
    
        std::ifstream file(verzeichnis); // <== Filename eintragen
      // Hierzu haette ich noch eine Frage
        std::vector<double> values;
    
        for(double d; file>>d;) // Werte einlesen; bis eine Fehler auftritt
        {
            values.push_back(d); // Werte in 'values' ablegen
    
    /*
    Hier wuerde ich gerne einen inkrementierenden integer haben, der bei jedem eingelesenen Wert auslöst.
    
    Sobald ein Zeilenumbruch '\n' erreicht wird, soll der integer nicht mehr weiterzaehlen.
    
    Im Gegenzug soll ebenfalls die Anzahl der Zeilenumbrüche mitgezählt werden.
    */
    
        }
        // std::cout << values.size() << " Werte gelesen" << std::endl;
    }
    

    Mit der Anzahl von Spalten und Zeilen kann ich nachher eigenständig den Vektor values in ein dynamisches zweidimensionales Array umschreiben. Das ist zwar in Workaround, macht aber für mich erstmal keine Probleme.

    Kann mir irgendeiner zu meinem Kommentator im Quellcode einen Implementierungstipp bitte geben?

    2.

    Ein Ausschnitt aus dem oben komplett gezeigten Quellcode:

    std::string verzeichnis;
        std::cout << "Dateiverzeichnis: ";
        std::cin >> verzeichnis; 
    
        std::ifstream file(verzeichnis); // <== Filename eintragen
      // Hierzu haette ich noch eine Frage
        std::vector<double> values;
    

    Muss ich bei dem string verzeichnis die \ schon als '\' eingeben?
    Wenn ja (was ich auch denke), gibt es bei der string-klasse eine Funktion, die einen einzelnen char aufspürt und ihn austauscht?

    Ich würde dann gerne als Pseudocode:

    Durchsuche verzeichnis nach char \
    Wenn \ gefunden, 
            dann ersetze mit '\\'
    Wenn verzeichnis durchlaufen ist, 
            return
    

    3.

    Das hat eigentlich nichts mit Zahlen zu tun. Allerdings würde ich, weil ich den Quellcode aus diesem Thread stammt, meine Frage kurz stellen.

    Ich möchte ein Startskript schreiben:

    Startanzahl: 1100
    Endzahl: 1200
    Speicherort: c:\\bla bla\\
    modus: nichts
    

    Hierzu eignet sich meiner Meinung nach die Suche aus dem obigen Quellcode.

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <limits> // std::numeric_limits< std::streamsize >
    
    int main()
    {
        std::vector<std::string> values;  // konfigurierbare Menupuenkte im Skript
        values.push_back("Startanzahl:");
        values.push_back("Endanzahl:");
        values.push_back("Speicherort:");
        values.push_back("modus:");
    
        std::vector<std::string> option;  // gewahlte Menupuenkte
    
        std::ifstream file("C:\\Users\\...\\Desktop\\master.txt"); // <== Filename eintragen
    
    for(int k = 0; k <= values.size(); k++){
    
        for( std::string material; file >> material; ) // lese Wort für Wort
        {
            if( material == values[k] ) // prüfe, ob das gelesene Wort 'material' mit 'values[k]' über ein stimmt
                break; // gesuchtes Material gefunden; dann Suche abbrechen
        }
    
    // Hier weiss ich nicht mehr eigenständig weiter. Siehe unten im Thread
    
    }
    }
    }
    

    Wenn ich einen Menuepunkt gefunden habe, möchte ich die gewählte Option einlesen.
    Ich würde gerne nicht so penibel drauf achten, wieviele Leerzeichen zwischen dem ':' und dem ersten char sind. Also bräuchte ich einen Funktion, die erst ein Wort einliest, wenn es kein ' ' ist. Am Besten wäre auch eine Implemtierung, in der ich auch einen konfigurierbare Menupuenkte im Skript nicht mit einem ':' beenden muss, sondern auch hier Leerzeichen einfügen kann.
    Beispiel:

    Startanzahl  :   1100
    Endzahl :  1200
    

    Die gewählte Option sollte mit einem Zeilenumbruch aufhören (siehe Beispielsskript oben).

    Mögliche Zahlen würde ich später via stoi o.Ä. casten.

    Weiß einer, wie ich das implementiere?

    Danke & cu

    John



  • Hallo John,

    zu 1.)

    #include "is_endl.h" // s. http://www.c-plusplus.net/forum/p1940874#1940874
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <limits> // std::numeric_limits< std::streamsize >
    
    int main()
    {
        std::string verzeichnis;
        std::cout << "Dateiverzeichnis: ";
        std::cin >> verzeichnis;
    
        std::ifstream file(verzeichnis); // <== Filename eintragen
        std::vector< std::vector< double > > values; // alle Werte quasi 2-dimensional
    
        for( int idxZeile = 0; file; ++idxZeile )
        {
            // -- eine Zeile lesen
            std::vector<double> werte_einer_zeile;
            // Hier wuerde ich gerne einen inkrementierenden integer haben, der bei jedem eingelesenen Wert auslöst.
            int inkrementierender_Integer = 0;
            for( double d; !is_endl( file ) && file >> d; ++inkrementierender_Integer )
                werte_einer_zeile.push_back(d); // Werte in 'values' ablegen
            values.push_back( werte_einer_zeile ); // Werte aus einer Zeile merken
    
            // Im Gegenzug soll ebenfalls die Anzahl der Zeilenumbrüche mitgezählt werden.
            // --> s. idxZeile
        }
    }
    

    Das Erkennen eines Zeilenendes ist nicht so einfach, weil es genau wie Space zu den white-space-charactern gehört und somit normalerweise schlicht überlesen wird. Aber da das immer wieder gefragt wird, habe ich mal ein is_endl gebastelt - siehe Link im Code oben.
    wobei noch zu bemerken ist, dass Du jeden Vektor nach der Anzahl seiner Werte fragen kannst (vector::size()).

    Zu 2.)

    Johnny_walk schrieb:

    Muss ich bei dem string verzeichnis die \ schon als '\' eingeben?
    Wenn ja (was ich auch denke), gibt es bei der string-klasse eine Funktion, die einen einzelnen char aufspürt und ihn austauscht?

    Ja- Du musst das mit angeben. Ja - es gibt eine Methode; besser zwei Methoden string::find() und string::replace().
    Und - Nein - das kannst Du hier nicht machen, da das '\' nur in dem Literal notwendig ist und gar nicht im string ankommt. Das '\' ist ein sogenanntes Fluchtsymbol, was dem Compiler angibt, dass da jetzt was kommt, was man normalerweise nicht in den Text schreiben kann.
    Z.B. wird "C:\normal\tag\\egal" 'übersetzt' mit "C:" + <LF> + "ormal" + <Tab> + "ag\egal". <LF> ist Code 10 und <Tab> ist Code 9
    Wenn Deine Umgebung das '/' auch als Directorie-Trenner akzeptiert, so benutze besser dies.

    Zu 3.)

    Johnny_walk schrieb:

    Ich würde gerne nicht so penibel drauf achten, wieviele Leerzeichen zwischen dem ':' und dem ersten char sind. Also bräuchte ich einen Funktion, die erst ein Wort einliest, wenn es kein ' ' ist.

    mach Dir keinen Kopf um die Leerzeichen, da können auch ein oder mehrere Zeilenumbrüche stehe - das wird korrekt gelesen. Der std::istream ist so gemacht, dass er Leerzeichen bzw. white-sapce-character (s.o.) zwar als Trenner akzeptiert, aber es im völlig egal ist, wie viele davon da stehen.

    Johnny_walk schrieb:

    Startanzahl: 1100
    Endzahl: 1200
    Speicherort: c:\\bla bla\\
    modus: nichts
    

    Also ein:

    string token;
        if( getline( file >> ws, token, ':' ) >> wert )
        {  // 'token' und 'wert' sind ohne Fehler gelesen
    

    reicht aus um dieses Format einzulesen; probiere das einfach mal aus. Das 'c:\\bla bla\' wird auch genau so gelesen - mit jeweils zwei(!) '\' - korrekt ist in der Datei: 'c:\bla bla\'

    Johnny_walk schrieb:

    Am Besten wäre auch eine Implemtierung, in der ich auch einen konfigurierbare Menupuenkte im Skript nicht mit einem ':' beenden muss, sondern auch hier Leerzeichen einfügen kann.

    Mit obigen Code am einfachsten zu erreichen, indem Du nach dem Einlesen von 'token' alle Leerzeichen die rechts stehen, beseitigst.

    :xmas2: Werner



  • Danke Werner Salomon,

    ich habe gestern noch viel ausprobiert und habe mich in einige Libaries eingelesen. Das meiner Ansicht unangenehmste ist, dass ich die Länge einer TXT-Zeile nicht abschätzen konnte. Damit viel

    http://www.cplusplus.com/reference/istream/istream/getline/

    schein mal raus, weil ich zwar, meiner bisherigen Meinung nach, '\n' als Delimiter festlegen konnte, aber bei dem Parameter streamsize auf den Schlauch stand.

    Ich bin deswegen ersmal über gegangen, die Zeilen zu erkennen. Mittels Internet habe ich folgendes geschafft:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <limits> // std::numeric_limits< std::streamsize >
    
    int main()
    {
        std::string verzeichnis = // TXT-Datei 
    
        std::ifstream file(verzeichnis); // <== Filename eintragen
    	std::ifstream columscounter(verzeichnis);
        std::vector<double> values;
     	bool row = true;
    	unsigned int count_row = 0;
    
    for(double d; file>>d;) // Werte einlesen; bis eine Fehler auftritt
        {
    		values.push_back(d); // Werte in 'values' ablegen
        }
    
    while ( std::getline(columscounter, std::string()) )
       ++count_row;
    
        std::cout << values.size() << " Werte gelesen" << std::endl;
    
    	std::cout << count_row << " Zeilen gelesen" << std::endl;
    }
    

    Das ist zwar ineffizient, aber hat die richtigen Werte ausgegeben. Mittels der size_of() von values konnte ich damit die Zeilenanzahl ermitteln (Matrix und so).

    2)

    Mir ist auch shcon aufgefallen, dass es besser sei mit / zu arbeiten. In meinen jämmerlichen Versuchen das '\n' einzufangen, wollte ich die Funktion

    http://www.cplusplus.com/reference/istream/istream/peek/

    benutzen und hatte halt Probleme mit '\'. Das ist ja quasi wie ein Quant und lässt sich nicht fangen 😉

    3)

    Dazu hatte ich mir noch keine Gedanken gemacht. Allerdings ist mir beim Debuggen aufgefallen, dass die Leerzeichen übersrpungen werden.

    Ob er daher auch ein Verzeichnis mit leerzeichen im Skript einliest, keine Ahnung. Ich werde es ausprobieren.

    Danke und tschüss

    Johnny_walk


Anmelden zum Antworten