TXT Tabelle Auslesen und Auswerten



  • Hallo liebes Team,

    wir müssen auf der FH eine Tabele einlesen und auswerten.
    Das einlesen der Tabelle funktioniert soweit.

    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    int main()
    {
    
    	string line;
    	ifstream file("WorldWealth.txt");
    	if (file.is_open())
    	{
    		while (getline(file, line))
    		{
    
    				cout << line << '\n';
    
    		}
    		file.close();
    	}
    	else {
    		cout << "file is not open" << '\n';
    
    	}
    
    	return 0;
    
    }
    

    Jedoch habe ich einfach keine Ahnung wie ich diese Tabelle auswerten kann.
    Auswerten bedeutet z.B. die Top 10 der Liste ausgeben und die Summe des Geldes aller Leute ausgeben.

    Hier ein Textauszug aus der liste:

    Billionaire list 2013 by Nation
    Rank	Name	Citizenship	Age	Net Worth ($US billion)	Source of Wealth
    Angola    Top
    736	Isabel dos Santos	Angola	40	2	investments
    Argentina    Top
    219	Carlos and Alejandro Bulgheroni	Argentina	-	5.5	oil and gas
    831	Eduardo Eurnekian	Argentina	70	1.8	cable tv, agriculture
    974	Gregorio Perez Companc	Argentina	77	1.5	oil and gas
    1175	Maria Ines de Lafuente Lacroze	Argentina	68	1.2	inheritance
    1268	Alberto Roemmers	Argentina	55	1.1	pharmaceuticals
    Australia    Top
    36	Georgina Rinehart	Australia	59	17	mining
    175	Ivan Glasenberg	Australia	56	6.7	commodities
    198	James Packer	Australia	45	6	gaming
    211	Andrew Forrest	Australia	51	5.7	mining
    229	Frank Lowy	Australia	82	5.3	shopping malls
    

    Vielen Dank!



  • Du musst die Daten in Varaibalen einer geeigneten Struktur einlesen.

    Du musst line in passende Teile zerlegen und diese dann in der Struktur ablegen.


  • Mod

    DirkB schrieb:

    Du musst die Daten in Varaibalen einer geeigneten Struktur einlesen.

    Du musst line in passende Teile zerlegen und diese dann in der Struktur ablegen.

    Oder sich den Umweg über line sparen und gleich die passend zerstückelte Information einlesen.



  • speednik2 schrieb:

    wir müssen auf der FH eine Tabele einlesen
    ...
    Jedoch habe ich einfach keine Ahnung wie

    Kann's sein dass du in der falschen Schule bist?



  • Wie sieht die Datei denn genau aus?
    Wenn du Glück hast haben die Felder eine feste Breite, kannst du dazu was sagen?



  • Bei genauerem Betracht handelt es sich hier um ein invalides Textformat. Wenn du uns die Datei also exakt so zeigst, wie von deinem Lehrer vorgegeben, darfst du dich nächstes Mal beim Lehrer beschweren.



  • DocShoe schrieb:

    Wie sieht die Datei denn genau aus?
    Wenn du Glück hast haben die Felder eine feste Breite, kannst du dazu was sagen?

    Der Ausschnitt oben, sieht nach Tabulator aus.

    Du müsstest demnach die einzelnen Zeilen splitten mit dem Trennzeichen TAB.

    Zum Thema splitten von Strings solltest du ausreichend Infos finden.

    Edit: Ein paar Worte sind allerdings irgendwie aus der Reihe...

    Edit2: Sind doch nicht aus der Reihe. Es handelt sich offenbar um eine Art Trenner für einzelne Ländergruppen. Angola, Argentina, Australia
    Das musst du berücksichtigen.



  • fdefde schrieb:

    Bei genauerem Betracht handelt es sich hier um ein invalides Textformat. Wenn du uns die Datei also exakt so zeigst, wie von deinem Lehrer vorgegeben, darfst du dich nächstes Mal beim Lehrer beschweren.

    Nun, es sind zwei Kopzeilen, die kann man überlesen.
    Dann kommt eine mit "Top" am Ende und dem Land an erster Stelle. Das kann man erkennen.

    Eine Eintrag erkennt man an der Zahl am Anfang (Rank).
    Der Name geht bis zum Land, das kennt man ja von der Zeile mit dem "Top"
    Danach kommen die weiteren Einträge, durch Leerzeichen getrennt.

    Es sind dann wohl Tabulatoren. Macht es einfacher

    Bis mal wieder eine Zeile mit "Top" kommt und demnach einem neuen Land.

    Übles Format, aber machbar.

    Ob der Weg ohne line (als Anfänger) einfacher ist ...?



  • Tatsächlich, der Kram ist mit Tabulatoren getrennt. Braves temi 👍

    DirkB: Nein.



  • Entschuldigung,
    Die Datensätze sind wie geschrieben wurde mit Tabulatoren getrennt.

    Sollte ich dann am besten z.B. eine Klasse erstellen in der ich die bestimmte Struktur ablege ?

    Wie sieht das dann mit der Auswertung aus müsste ich die einzelnen Datensätze dafür nicht in geeignete Arrays einlesen bzw in einen JaggedArray ?

    Edit1:

    Ich könnte doch eine Klasse namens Person anlegen mit den verschiedenen Datensätzen und anschließend in der main mit zB strtok und eine while schleife mehrere Personen anlegen der Vergleich wäre anschließend ein Kinderspiel oder ?



  • In C++ kannst du einfach per

    ifstream file("WorldWealth.txt");
    
    int rank;
    string name;
    file << rank << name // << ...;
    

    die Daten einlesen (sofern die Texte durch Whitespaces (Leerzeichen, Zeilentrenner, Tabulatoren, ...) getrennt sind).
    Du kannst aber auch explizit alles bis zum nächsten Tabulator einlesen:

    getline(file, name, '\t');
    

    (falls im Namen selbst Leerzeichen enthalten sind)



  • Du brauchst eine Datenstruktur, die sämtliche Informationen zu einer Person enthält.
    Da dort verschiedene Typen (int, double, Text) enthalten sind, kannst du kein Array nehmen.

    Damit legst du dann ein Feld (Array oder ähnliches) an.

    In der main machst du sehr wenig, du schreibst zum Einlesen eine eigene Funktion.
    Und strtok ist auch nicht mehr so der Hit.



  • Th69 schrieb:

    (falls im Namen selbst Leerzeichen enthalten sind)

    Ja, ja das sind sie.

    Maria Ines de Lafuente Lacroze



  • Die Einträge sind durch Tabulatoren getrennt. Leider stehen auch nochmal Trennzeilen in der txt-Datei z.B. "Argentina Top" und das Alter kann auch durch einen '-' dargestelt sein. Das macht die Datei etwas 'unleserlich'. Bekommt man aber alles hin - und so geht es dann:

    #include <cctype> // isdigit
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <limits> // numeric_limits<>
    #include <vector>
    
    std::istream& skipline( std::istream& in )
    {
        const std::streamsize ALLES = std::numeric_limits< std::streamsize >::max();
        return in.ignore( ALLES, '\n');
    }
    
    struct Billionaire
    {
        int rank;
        std::string name;
        std::string citizenship;
        int age;
        double worth;
        std::string source;
    };
    
    struct Age  // liest das Alter, kann auch ein '-' sein!
    {   
        Age( int& age )
            : age( age )
        {}
        int& age;
    };
    std::istream& operator>>( std::istream& in, Age age_reader )
    {
        char c;
        if( in >> c && std::isdigit( c ) )
            in.putback(c) >> age_reader.age;
        else
            age_reader.age = 0;
        return in;
    }
    
    std::istream& skip_none_number( std::istream& in )   // überspringt eine Zeile ohne Ziffer am Anfang
    {
        char c;
        if( in >> c && std::isdigit( c ) )
            return in.putback( c );
        return in >> skipline;
    }
    
    // das ist die eigentliche Lesefunktion für einen Eintrag in der Datei
    std::istream& operator>>( std::istream& in, Billionaire& billy )
    {
        in >> skip_none_number >> billy.rank;
        getline( in.ignore(), billy.name, '\t' ); // ignore: führenden Tabulator überlesen
        getline( in, billy.citizenship, '\t' );
        in >> Age(billy.age) >> billy.worth;
        getline( in.ignore(), billy.source, '\n' ); // Rest der Zeile
        return in;
    }
    
    int main()
    {
        using namespace std;
    
        ifstream file("WorldWealth.txt");
        if( !file.is_open() )
        {
            cerr << "Fehler beim Oeffnen der Datei" << endl;
            return -2;
        }
        file >> skipline >> skipline;   // ersten zwei Zeilen ignorieren
        std::vector< Billionaire > billies;
        for( Billionaire b; file >> b; )
        {
            cout << "'" << b.name << "' gelesen" << endl;
            billies.push_back( b );
        }
        cout << billies.size() << " Eintraege gelesen" << endl;
    
        return 0;
    }
    

Anmelden zum Antworten