W
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;
}