for_each ausgabe einer klasse
-
Ja, da du den Header
"adresse.h"indirekt über"adressliste.h"auch inkludierst, ist die Klasse dort bekannt.
-
Gustl schrieb:
Gut, ich habe jetzt euer std:: nicht befolgt, aber daran kann es doch wirklich nicht liegen oder?
Nein, aber ich rate dir wirklich dringen vom using namespace in Headern (sowie vor includes) ab. Wenn du einmal mehrere Bibliotheken verwendest oder ein großes Projekt hast, ist der Aufwand dies nachträglich bei Namenskonflikten (Die immer realistischer werden um so mehr Bibliotheken oder allgemein Code vorliegt) zu korrigieren meist höher als der Aufwand wenn man es gleich macht.
using namespace sollte man so lokal wie möglich verwenden, in einen Header wird es aber sehr leicht zu einer globalen Einstellung über das Gesamtprojekt.
Es spricht wenig dagegen es in Sourcedateien (Dann muss man nur die Dateien anpassen wo tatsächlich Mehrdeutigkeiten auftreten), oder in Funktionsrümpfen zu verwenden.
-
neues problem mit sort...hmpf
folgender code:
void Adressliste::sortieren() { std::sort(liste.begin(), liste.end(), sortname); }sortname ist in der adresse.h mit friend deklariert.
friend bool sortname(const Adresse &a, const Adresse &b);methode dazu in der adresse.cpp:
bool sortname(const Adresse &a, const Adresse &b) { if(a.hausnr < b.hausnr)return true; else return false;Fehlermeldungen:
Fehler 7 error C2784: "reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)": template-Argument für "const std::reverse_iterator<_RanIt> &" konnte nicht von "std::list<_Ty>::_Iterator<_Secure_validation>" hergeleitet werden. c:\program files\microsoft visual studio 8\vc\include\algorithm 2903Fehler 8 error C2784: "reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)": template-Argument für "const std::reverse_iterator<_RanIt> &" konnte nicht von "std::list<_Ty>::_Iterator<_Secure_validation>" hergeleitet werden. c:\program files\microsoft visual studio 8\vc\include\algorithm 2903
Fehler 9 error C2784: "reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)": template-Argument für "const std::reverse_iterator<_RanIt> &" konnte nicht von "std::list<_Ty>::_Iterator<_Secure_validation>" hergeleitet werden. c:\program files\microsoft visual studio 8\vc\include\algorithm 2903
Fehler 10 error C2784: "reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)": template-Argument für "const std::reverse_iterator<_RanIt> &" konnte nicht von "std::list<_Ty>::_Iterator<_Secure_validation>" hergeleitet werden. c:\program files\microsoft visual studio 8\vc\include\algorithm 2903
Fehler 11 error C2676: Binärer Operator '-': 'std::list<_Ty>::_Iterator<_Secure_validation>' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht c:\program files\microsoft visual studio 8\vc\include\algorithm 2903
Fehler 12 error C2780: 'void std::_Sort(_RanIt,_RanIt,_Diff)': Erwartet 3 Argumente - 4 unterstützt c:\program files\microsoft visual studio 8\vc\include\algorithm 2903Versteh ich nicht, dies ging z.B. wieder mit den borland... hmpf
ich übergebe doch 3 parameter...Habe auch schon probiert den operator < zu überlagern... und somit dann nur
std::sort(liste.begin(), liste.end());angeben, habe gelesen das man mit den < operator nur an sort zwei parameter übergeben muss, quasi anfang und ende... geht aber auch nicht...
@asc
Ja, ich sollte es mir gewiss angewöhnen, aber wenn das unser Lehrer nicht macht, gewöhne ich es mir vorerst nicht an.
Da wir die Prüfungen per hand schreiben und er das auch komischerweise nicht will^^MfG Gustl
-
Du kannst
std::sort()nicht auf einestd::listanwenden, da diese keine Random-Access-Iteratoren unterstützt. Benutze dazu die Memberfunktionstd::list::sort().
-
ahhh, da liegt der hund begraben.. stimmt mit einem programm vauf borland habe ich auch deque verwendet. danke
-
Noch eine kleine Verständnisfrage zu const:
heißt es nun so
friend ostream& operator<<(ostream& outstream, const Adresse & adresse);oder doch so
friend ostream& operator<<(ostream& outstream, Adresse const & adresse);?
-
Ist das gleiche. Was dir lieber ist.
Grüssli
-
Also langsam vergeht mir der Spaß...
Jetzt bringt der Compiler von Visual Studio auch einen Überlauf Fehler...
Hier der Code:
//main.cpp------------------------------------------------------------------------- #include <string> #include <iostream> #include <list> #include "adressliste.h" const char dateiname[]="datei.txt"; int main() { Adressliste Freunde; //--einfuegen--------------------------------------------------------------------- Adresse Address1("Denny","Fischer","fuckweg","8","08484-234"); Adresse Address2("Heid","Stefan","langweg","23","08484-297"); Adresse Address3("Schoeninger","Sebastian","kurzweg","4","0848-1984"); std::cout<<"3 Adressen in Objekt einfuegen..."<<std::endl; Freunde.einfuegen(Address1); Freunde.einfuegen(Address2); Freunde.einfuegen(Address3); //--speichern--------------------------------------------------------------------- std::cout<<std::endl<<"speichern..."<<std::endl; Freunde.savetofile(dateiname); //--ausgeben---------------------------------------------------------------------- std::cout<<std::endl<<"ausgeben auf console..."<<std::endl; Freunde.ausgabe(); //--sortieren--------------------------------------------------------------------- std::cout<<std::endl<<"sortieren..."<<std::endl; Freunde.sortieren(); //--ausgeben---------------------------------------------------------------------- std::cout<<std::endl<<"ausgeben auf console (sortiert)..."<<std::endl; Freunde.ausgabe(); //--loeschen---------------------------------------------------------------------- std::cout<<std::endl<<"loeschen...dann leere liste ausgeben..."<<std::endl; Freunde.loeschen(); Freunde.ausgabe(); //--laden------------------------------------------------------------------------- std::cout<<std::endl<<"laden von file..."<<std::endl; Freunde.loadfromfile(dateiname); //--ausgeben---------------------------------------------------------------------- std::cout<<std::endl<<"geladene lsite ausgeben..."<<std::endl; Freunde.ausgabe(); getchar(); return 0; } //--------------------------------------------------------------------------------//adresse.h------------------------------------------------------------------- #ifndef adresseH #define adresseH #include <string> #include <iostream> class Adresse { std::string name; std::string vorname; std::string street; std::string hausnr; std::string phone; public: Adresse( std::string name="", std::string vorname="", std::string street="", std::string hausnr="", std::string phone="") : name(name), vorname(vorname), street(street), hausnr(hausnr), phone(phone) {} friend std::ostream& operator<<(std::ostream& outstream, Adresse const & adresse); friend std::istream& operator>>(std::istream& instream, Adresse const & adresse); friend bool sortname(const Adresse &a, const Adresse &b); }; //--------------------------------------------------------------------------- #endif//adresse.cpp---------------------------------------------------------------- #include "adresse.h" #include <string> #include <iostream> std::ostream& operator<<(std::ostream& outstream, Adresse const & adresse) { outstream << adresse.name << " " << adresse.vorname << " " << adresse.street << " " << adresse.hausnr << " " << adresse.phone << std::endl; return outstream; } std::istream& operator>>(std::istream& instream, Adresse const & adresse) { instream >> adresse.name; instream >> adresse.vorname; instream >> adresse.street; instream >> adresse.hausnr; instream >> adresse.phone; return instream; } bool sortname(const Adresse &a, const Adresse &b) { if(a.name < b.name)return true; else return false; } //---------------------------------------------------------------------------//adressliste.h--------------------------------------------------------------- #ifndef adresslisteH #define adresslisteH #include <deque> #include "adresse.h" class Adressliste { std::deque<Adresse> liste; std::deque<Adresse>::iterator it; public: void einfuegen(Adresse const & address); void savetofile(char const *dateiname); void loadfromfile(char const *dateiname); void sortieren(); void ausgabe(); void loeschen(); }; //--------------------------------------------------------------------------- #endif//adressliste.cpp----------------------------------------------------------------- #include "adressliste.h" #include <string> #include <iostream> #include <fstream> #include <deque> #include <algorithm> void Adressliste::einfuegen(Adresse const & address) { liste.push_back(address); } void Adressliste::savetofile(char const *dateiname) { std::fstream f; f.open(dateiname, std::ios::out); if(!f)std::cout<<"--- Fehler beim Oeffnen der Datei \"datei.txt\"! ---"<<std::endl; else { for(it= liste.begin(); it != liste.end(); ++it) f<<*it; std::cout<<"--- Liste in "<<dateiname<<" gespeichert! ---"<<std::endl; } f.close(); } void Adressliste::loadfromfile(char const *dateiname) { std::fstream f; Adresse tmp; f.open(dateiname, std::ios::in); if(!f)std::cout<<"--- Fehler beim Oeffnen der Datei \"datei.txt\"! ---"<<std::endl; else { f>>tmp; while(!f.eof()) { liste.push_back(tmp); f>>tmp; } std::cout<<"--- Liste aus "<<dateiname<<" geladen! ---"<<std::endl; f.close(); } } void Adressliste::sortieren() { std::sort(liste.begin(), liste.end(), sortname); } void Adressliste::ausgabe() { for(it= liste.begin(); it != liste.end(); ++it) std::cout<<*it; } void Adressliste::loeschen() { liste.clear(); }sobald er also von der file laden will hat er überlauf...
das programm läuft bis zum Freunde.loadfromfile(dateiname); da ist dann schluss und es kommt die fehlermeldung:
Fehlermeldung von Visual:
"Unbehandelte Ausnahme bei 0x004143e7 in adresse.exe: 0xC00000FD: Stack overflow."Mach echt keinen Spaß mehr...
-
Wann kracht es denn überhaupt? Direkt beim starten, beim schreiben, beim lesen? Bist Du mal mit dem Debugger durchgesteppt?
Ansonsten noch zwei Kleinigkeiten:
Für
if(a.name < b.name)return true; else return false;gibt es die geheime Kurzschreibweise
return a.name < b.name;Du brauchst außerdem Deine streams nicht selber schließen, das mach der Destruktor für Dich. Zum einlesen würde ich einen ifstream nehmen, zum rausschreiben einen ofstream. Außerdem ist der Vergleich mit eof möglicherweise nicht ganz das was Du willst. Ich würde die Einleseroutine etwa wie folgt schreiben:
void Adressliste::loadfromfile(char const *dateiname) { std::ifstream f(dateiname); if(!f) { std::cout<<"--- Fehler beim Oeffnen der Datei \"datei.txt\"! ---"<<std::endl; return; } for(Adresse tmp;f>>tmp;) liste.push_back(tmp); std::cout<<"--- Liste aus "<<dateiname<<" geladen! ---"<<std::endl; }
-
Jester schrieb:
Wann kracht es denn überhaupt? Direkt beim starten, beim schreiben, beim lesen? Bist Du mal mit dem Debugger durchgesteppt?
Der Überlauf muss mit der Methode loadfromfil geschehen.. wenn ich es ausklammer funktioniert das programm. Aber auch mit deiner Version gehts leider nicht und es kommt zum überlauf...
Jester schrieb:
Für
if(a.name < b.name)return true; else return false;gibt es die geheime Kurzschreibweise
return a.name < b.name;Richtig, habe ich auch schon gesehen, aber bin nicht drauf gekommen...
Danke.Jester schrieb:
Du brauchst außerdem Deine streams nicht selber schließen, das mach der Destruktor für Dich.
Wo genau schließe ich die selbst?
Jester schrieb:
Zum einlesen würde ich einen ifstream nehmen, zum rausschreiben einen ofstream. Außerdem ist der Vergleich mit eof möglicherweise nicht ganz das was Du willst. Ich würde die Einleseroutine etwa wie folgt schreiben:
void Adressliste::loadfromfile(char const *dateiname) { std::ifstream f(dateiname); if(!f) { std::cout<<"--- Fehler beim Oeffnen der Datei \"datei.txt\"! ---"<<std::endl; return; } for(Adresse tmp;f>>tmp;) liste.push_back(tmp); std::cout<<"--- Liste aus "<<dateiname<<" geladen! ---"<<std::endl; }Wie gesagt, wenn ich meinen mit deinem code ersetze habe ich das gleiche Problem.

Edit:
nach der Fehlermeldung öffnet mir visual die datei xstring
und bringt mir einen pfeil aufsize_type __CLR_OR_THIS_CALL max_size() const { // return maximum possible length of sequence size_type _Num = _Mybase::_Alval.max_size(); return (_Num <= 1 ? 1 : _Num - 1); }zudem ist mir auch nicht ganz klar was hier genau passiert:
for(Adresse tmp;f>>tmp;) liste.push_back(tmp);Könnte mir das vielleicht wer kurz erklären?
-
Wo sind denn die Fachmänner die mir sagen können warum ich bei loadfromfile(..) ein stack overflow bekomme/verursache?
Wäre echt klasse wenn mir hier einer licht ins dunkle bringt.
-
Gustl schrieb:
Wo sind denn die Fachmänner die mir sagen können warum ich bei loadfromfile(..) ein stack overflow bekomme/verursache?
Ich habe dir schon vor zwei Seiten gesagt, du solltest einen Debugger benutzen. Solche Dinge sind eigentlich deine Aufgabe. Wenn wir nicht gerade etwas im Code sehen, können wir dir auch nicht helfen. Prüf doch die Variablen auf ihre Gültigkeit. Wenn du im Debug-Mode ausführst, sollte dir die STL bei Fehlern passende Assertions liefern.
for(Adresse tmp;f>>tmp;) liste.push_back(tmp);Das funktioniert wie jede For-Schleife. Zu Beginn wird ein
Adresse-Objekt namenstmperstellt. Während der Ausdruckf>>tmpwahr ist (solange eingelesen wird und der Stream sich in einem korrekten Zustand befindet), wird an die Liste angehängt. Hier würde ich allerdings eher eine While-Schleife nehmen. Wird die Schleife durchlaufen? Endet sie?
-
Dann komme ich hier leider nicht mehr weiter, trotzdem danke.
-
Bist Du sicher, dass der Code genauso aussieht wie Du oben sagst? Mich wundert ein bißchen, dass Du eine const-Referenz im operator>> hast.
-
Gustl schrieb:
Dann komme ich hier leider nicht mehr weiter, trotzdem danke.
Nette Einstellung. Erwartest du jetzt, dass wir den Code selber versuchen zu kompilieren - in der Hoffnung, dein Verhalten zu reproduzieren und den Fehler zu lokalisieren?
Wir haben dir schon viele Hinweise gegeben, um die du dich nicht sonderlich zu kümmern scheinst. Wenn du das mit dem Debugger nicht ernst nimmst, dann kommst du eben nicht weiter. Aber du kannst mir glauben, das war nicht das letzte Problem dieser Art. Von daher würde ich mir das mit dem Debugger nochmals überlegen. Wie gesagt wären auch Konsolenausgaben ein Anfang.
-
Jester schrieb:
Bist Du sicher, dass der Code genauso aussieht wie Du oben sagst? Mich wundert ein bißchen, dass Du eine const-Referenz im operator>> hast.
Ja, genauso sieht der code aus, asc hat mir empfohlen bei operator>> const zu verwenden, da diese Übergabeparameter ja auch nicht verändert werden, ist das wohl falsch?
Nexus schrieb:
Nette Einstellung. Erwartest du jetzt, dass wir den Code selber versuchen zu kompilieren - in der Hoffnung, dein Verhalten zu reproduzieren und den Fehler zu lokalisieren?
Wir haben dir schon viele Hinweise gegeben, um die du dich nicht sonderlich zu kümmern scheinst. Wenn du das mit dem Debugger nicht ernst nimmst, dann kommst du eben nicht weiter. Aber du kannst mir glauben, das war nicht das letzte Problem dieser Art. Von daher würde ich mir das mit dem Debugger nochmals überlegen. Wie gesagt wären auch Konsolenausgaben ein Anfang.
Nein, ich möchte nicht, dass ihr den Code selbst kompiliert und mir sagt wo der genaue Fehler liegt, oder vielleicht doch? Ich habe lediglich gefragt was an diesem code falsch sein soll, fakt ist das er beim operator >> den stack overflow bringt und zwar beim Laden von einer Datei.
Aber da nicht mal Spezialisten den genauen Fehler entdecken können, sehe ich für einen Anfänger wie mich auch nicht viel Land.Ich habe gestern bestimmt 2-3h probiert und gesucht wo der Hund begraben liegt, konnte jedoch keinen fehler im code finden, zudem der teil von operator >> überladen von asc kommt... genau dort ist dieser overflow... oder zumindest dort wo er versucht von der datei mit dem operator in ein objekt zu schreiben.
Somit wächst mir die ganze Sache über den Kopf und ich warf gestern die Flinte ins Korn.
Wenn mir hierbei keiner mehr helfen kann, werde ich die Datei zeilenweise auslesen und den string zum aufteilen an einer Funktion übergeben die eine Adresse zurückgibt, somit kommt es nicht mehr zum overflow, aber ich habe die aufgabe, mit den >> operator eine datei auszulesen, leider verfehlt.
Aber es funktioniert wenigstens.
Ich danke für eure Bemühungen und werde euch mit diesem Thema auch nicht mehr belästigen.
Ich habe in diesem Thema auch viel von euch gelernt. Danke.
MfG Gustl
-
Gustl schrieb:
Jester schrieb:
Bist Du sicher, dass der Code genauso aussieht wie Du oben sagst? Mich wundert ein bißchen, dass Du eine const-Referenz im operator>> hast.
Ja, genauso sieht der code aus, asc hat mir empfohlen bei operator>> const zu verwenden, da diese Übergabeparameter ja auch nicht verändert werden, ist das wohl falsch?
Es ist nicht nur falsch, sondern wäre auch gar nicht erst kompilierbar. Beim
operator <<ist die konstante Referenz korrekt, dort wird das Objekt schliesslich nicht verändert, aber beimoperator >>veränderst du das Objekt ja. Du liesst schliesslich in das Objekt ein. Daher ist es sehr wahrscheinlich, dass du uns nicht den richtigen Code gezeigt hast. Denn der gezeigte würde nicht kompilieren und daher wäre kein Stackoverflow möglich
Grüssli
-
@ Gustl:
Es ist mir bewusst, dass es sehr demotivierend sein kann, mehrere Stunden lang einen Fehler zu suchen. Es ist auch okay, dass du hier fragst, nur können wir dir auch beim besten Willen nicht mehr gross weiterhelfen. Dazu kommt, dass der Code mit grosser Wahrscheinlichkeit nicht dem entspricht, der den Fehler erzeugt (siehe Draveres Post). Vielleicht ist es auch möglich, dass mit dem Compiler etwas nicht stimmt.Das mit dem Debugger war nur ein guter Ratschlag, der kann dir Fehlersuche massiv vereinfachen.
-

genau das const muss hier an dieser Stelle raus... dann funktioniert es, auch ohne stack overflow.
Aber ich habe euch 100pro den Orginal code gezeigt und er komiliert auch mit den const beim operator >>... unglaublich aber wahr
Jetzt habt ihr mir doch geholfen.

Thx
MfG Gustl
-
In diesem Falle gibt es nur eins: Wechsle so schnell wie möglich den Compiler.
Dass er solch fehlerhaften Code zulässt und dadurch einen Laufzeitfehler erzeugt, kann es ja nicht sein.