Einzelne Elemente eines Strings in Variablen speichern



  • Guten Morgen miteinander,

    ich habe folgendes Problem.
    Ich habe aus einer Textdatei die einzelnen Zeilen als Strings gespeichert.
    Jede Zeile hat das gleiche Format, nämlich folgendes:

    "Filiale" "Auftragsnummer" "Auftragsdatum" "Name" "Vorname" "Geburtsdatum" "Straße"
    

    Die Einträge sind also von Hochkommata umschlossen und durch Tab getrennt.
    Ich möchte nun jeden einzelnen Eintrag in eine Variable speichern.
    Also Filiale in einen integer, Auftragsnummer in einen integer, Datum in einen String, etc.

    Die Variablen sind in einer Klasse.
    Ich dachte mir, den String zeichenweise in einer Schleife abzuarbeiten, aber leider habe ich keine Ahnung, wie ich jetzt sagen soll, dass man die einzelnen Einträge dann in die Variablen speichert bzw. wie man erkennen kann, zwischen welchen Hochkommata welcher Eintrag steht...

    Ich hoffe ihr habt mein Problem verstanden
    Klassen und Methoden wurden schon gemacht, handelt sich also nur um dieses (kleine) Problem


  • Mod

    Du kannst einen stringstream verwenden und dann wie gewohnt aus diesem mit dem Operator >> auslesen. Genauso als würdest du aus std::cin lesen.



  • Habit schrieb:

    Ich habe aus einer Textdatei die einzelnen Zeilen als Strings gespeichert.

    brauchst Du diese Strings unbedingt?

    Habit schrieb:

    Jede Zeile hat das gleiche Format, nämlich folgendes:

    "Filiale" "Auftragsnummer" "Auftragsdatum" "Name" "Vorname" "Geburtsdatum" "Straße"
    

    Die Einträge sind also von Hochkommata umschlossen und durch Tab getrennt.
    Ich möchte nun jeden einzelnen Eintrag in eine Variable speichern.
    Also Filiale in einen integer, Auftragsnummer in einen integer, Datum in einen String, etc.

    Die Variablen sind in einer Klasse.

    schön - mal angenommen diese Klasse heißt 'Auftrag' - dann solltest Du zunächst einen Streaming-Operator schreiben, der alle Member genau eines Auftrags liest. Das mit den Variablen in Hochkomma ist auch kein Problem, nur für Text muss man eine Sonderbehandlung machen. Und dann liest Du die 'Aufträge' direkt aus der Datei - der Umweg über Zeilen und Strings ist unnötig. Alles zusammen sähe z.B. aus:

    #include <string>
    #include <iostream>
    #include <fstream>
    #include <vector>
    
    template< char C >
    std::istream& Char( std::istream& in ) // überliest das Zeichen C
    {
        char c;
        if( in >> c && c != C )
            in.setstate( std::ios_base::failbit );
        return in;
    }
    
    template< typename T >
    struct QuotedReader // liest eine Variable in Hochkommas
    {
        QuotedReader( T& x ) : m_x( x ) {}
        friend std::istream& operator>>( std::istream& in, const QuotedReader& qr )
        {
            return in >> Char<'"'> >> qr.m_x >> Char<'"'>;
        }
    private:
        T& m_x;
    };
    
    template<>
    struct QuotedReader< std::string > // Sonderbehandlung für Strings
    {
        QuotedReader( std::string& x ) : m_x( x ) {}
        friend std::istream& operator>>( std::istream& in, const QuotedReader& qr )
        {
            return getline( in >> Char<'"'>, qr.m_x, '"' );
        }
    private:
        std::string& m_x;
    };
    
    template< typename T >
    QuotedReader< T > quoted( T& x )
    {
        return QuotedReader< T >( x );
    }
    
    class Auftrag
    {
    public:
        friend std::istream& operator>>( std::istream& in, Auftrag& x ) // Streaming-Operator
        {
            return in >> quoted( x.m_filiale ) >> quoted( x.m_auftragsNr ) >> quoted( x.m_auftragsdatum ) 
                >> quoted( x.m_name ) >> quoted( x.m_vorname ) >> quoted( x.m_geburtsdatum ) >> quoted( x.m_strasse );
        }
    private:
        int m_filiale, m_auftragsNr;
        std::string m_auftragsdatum, m_name, m_vorname, m_geburtsdatum, m_strasse;
    };
    
    int main()
    {
        using namespace std;
        ifstream file( "input.txt" );
        vector< Auftrag > auftraege;
        for( Auftrag a; file >> a; )
            auftraege.push_back( a );
        if( file.eof() )
        {
            cout << "alles gelesen " << endl;
            // ...
        }
    
        return 0;
    }
    

    Gruß
    Werner


Anmelden zum Antworten