K
Ich sehe Dein Problem nicht. Ich mag es auch nicht suchen, viel lieber möchte ich Dir mal schrittweise auf die Schnelle mal einen einfacheren Weg zeigen.
(kann man sich auch aus der FAQ ableiten, ggf. isses aber auch was für. ka)
Als erstes verwenden wir std::string.
Wir kommen so zu einer struktur die ich mal so aussehen lasse:
struct person
{
string VName;
string NName;
int alter;
string TNummer;
};
Ich nehme an Du verwaltest Deine Leutchen in einer Liste. Hierfür verwende ich nun mal std::list.
Nun können wir bequem mit einer Schleife ähnlich wie Du es machst einlesen:
#include <iostream>
#include <string>
#include <fstream>
#include <list>
using namespace std;
struct person
{
string VName;
string NName;
int alter;
string TNummer;
};
int main(int argc, char* argv[])
{
// kennst Du ja bereits
std::ifstream datei("t:\\test.txt");
if(!datei)
return 20;
// unsere Liste die Kopien von person(en) aufnimmt
list<person> PersonenListe;
// Ich gehe hier davon aus das es garantiert ist das IMMER ganze Datensätze stehen.
person temp;
while(datei>>temp.VName) // Als erstes den Namen lesen und
{ // dabei prüfen ob das geklappt hat
// danach den rest lesen
datei>>temp.NName;
datei>>temp.alter;
datei>>temp.TNummer;
// und in die Liste anfügen
PersonenListe.push_back(temp);
}
// Kontrollausgabe
for(list<person>::iterator pos = PersonenListe.begin();pos != PersonenListe.end();++pos)
{
cout<<pos->VName<<' ';
cout<<pos->NName<<' ';
cout<<pos->alter<<' ';
cout<<pos->TNummer<<'\n';
}
}
Nun, das klappt schaut auch schon ganz hübsch aus.
Aber wir könnten noch die operatoren << und >> überladen. Somit schaffen wir es person überall da auszugeben und zu lesen wo >> und << verwendet wird.
(Dateien Bildschirmausgabe StringStreams u.v.m.)
Sie Signatur für diese Überladung sieht folgend aus:
istream & operator>>(istream & instream,person & temp);
ostream & operator<<(ostream & outstream,const person & temp);
Damit kannst Du nun so tun als wäre person ein eingebauter Datentyp.
cout<<"Der gewinner ist:"<<person;
Kein lästiges Ausgeben der Einzelnen Elemente jedesmal wenn Du was ausgeben willst. Du kannst bestimmen wie die Ausgabe ablaufen soll.
Die Funktion für die Ausgabe ist das gleiche wie zuvor, ohne Schleife:
istream & operator>>(istream & instream,person & temp)
{
instream>>temp.VName;
instream>>temp.NName;
instream>>temp.alter;
instream>>temp.TNummer;
return instream;
}
ostream & operator<<(ostream & outstream,const person & temp)
{
outstream<<temp.VName<<' ';
outstream<<temp.NName<<' ';
outstream<<temp.alter<<' ';
outstream<<temp.TNummer<<'\n';
return outstream;
}
Mit dieser Hilfe können wir das Einlesen und die Kontrollausgabe auf folnde Zeilen reduzieren:
while(datei>>temp)
PersonenListe.push_back(temp);
for(list<person>::iterator pos = PersonenListe.begin();pos != PersonenListe.end();++pos)
cout<<*pos;
Hier das gesammte zum Compilieren:
#include <iostream>
#include <string>
#include <fstream>
#include <list>
using namespace std;
struct person
{
string VName;
string NName;
int alter;
string TNummer;
};
istream & operator>>(istream & instream,person & temp);
ostream & operator<<(ostream & outstream,const person & temp);
istream & operator>>(istream & instream,person & temp)
{
instream>>temp.VName;
instream>>temp.NName;
instream>>temp.alter;
instream>>temp.TNummer;
return instream;
}
ostream & operator<<(ostream & outstream,const person & temp)
{
outstream<<temp.VName<<' ';
outstream<<temp.NName<<' ';
outstream<<temp.alter<<' ';
outstream<<temp.TNummer<<'\n';
return outstream;
}
int main(int argc, char* argv[])
{
std::ifstream datei("t:\\test.txt");
if(!datei)
return 20;
list<person> PersonenListe;
while(datei>>temp)
PersonenListe.push_back(temp);
for(list<person>::iterator pos = PersonenListe.begin();pos != PersonenListe.end();++pos)
cout<<*pos;
return 0;
}
Mich persönlich stören noch die Schleifen. Ich persönlich (schon mal in deckung geh) finde es viel schöner das ganze mit hilfe von copy zu realisieren.
Wir nutzen dabei die Hilfmittel istream:iterator ostream_iterator und copy:
copy(beg,end,back_inserter(PersonenListe));
copy(PersonenListe.begin(),PersonenListe.end(),ostream_iterator<person>(cout));
Du definierst die Person , packst es in eine Klasse, lieferst die operator<< und operator>> mit und schon kann sich das gesammte einlesen auf eine Zeile beschränken.
Hier mal das Fragment zum selbsttesten:
#include <iostream>
#include <string>
#include <fstream>
#include <list>
#include <iterator>
using namespace std;
struct person
{
string VName;
string NName;
int alter;
string TNummer;
};
istream & operator>>(istream & instream,person & temp);
ostream & operator<<(ostream & outstream,const person & temp);
istream & operator>>(istream & instream,person & temp)
{
instream>>temp.VName;
instream>>temp.NName;
instream>>temp.alter;
instream>>temp.TNummer;
return instream;
}
ostream & operator<<(ostream & outstream,const person & temp)
{
outstream<<temp.VName<<' ';
outstream<<temp.NName<<' ';
outstream<<temp.alter<<' ';
outstream<<temp.TNummer<<'\n';
return outstream;
}
int main(int argc, char* argv[])
{
std::ifstream datei("t:\\test.txt");
if(!datei)
return 20;
istream_iterator<person> beg(datei);
istream_iterator<person> end;
// Einlesen aller Personen der Datei.
// Wieder wird angenommen das ganze Datensätze vorhanden sind!
copy(beg,end,back_inserter(PersonenListe));
// Kontrollaugabe
copy(PersonenListe.begin(),PersonenListe.end(),ostream_iterator<person>(cout));
return 0;
}
Ich hoffe Dich auf neue Ideen gebracht zu haben