Aufgaben für C++
-
Ok hab des jetzt mal geändert, ist ja echt viel einfacher:D
Aber laufen tuts leider trotzdem noch net, poste dann mal wie gewünscht alles;-)main.cpp
#include <fstream> #include "classAdresse.h" #include "funktionen.h" using namespace std; int main() { bool stop = false; int auswahl; map<string, Adresse> Adressen; while( !stop ) { menu(auswahl); switch( auswahl ) { case 1: { adresseAnlegen( Adressen ); break; } case 2: { menuAuslesen( Adressen ); break; } case 3: { cout << "Programm wird beendet!"; stop = true; break; } } } }funktionen.cpp
#include "classAdresse.h" #include "funktionen.h" #include <iostream> #include <string> #include <map> #include <fstream> using namespace std; void menu( int& auswahl ) { cout << "Was wollen sie tun:\n"; cout << "Neue Adresse anlegen(1)\n"; cout << "Adresse suchen(2)\n"; cout << "Programm beenden(3)\n"; cin >> auswahl; if( ( auswahl < 1 ) || ( auswahl > 3 ) ) { cout << "Falsche Eingabe!\n"; menu(auswahl); } } void adresseAnlegen( map<string, Adresse>& Adressen ) { cout << "Geben sie den Vornamen ein: "; string vorname; cin >> vorname; cout << "Geben sie den Nachnamen ein: "; string nachname; cin >> nachname; cout << "Geben sie die Adresse ein: "; string adresse; cin.ignore(); getline( cin, adresse ); cout << "Geben sie die Telefonnummer ein: "; string tele; cin >> tele; cout << "Geben sie die Email-Adresse ein: "; string email; cin>> email; Adressen[vorname] = Adresse(vorname, nachname, adresse, tele, email); // Adresse wird erstellt in der map ofstream fout( vorname.c_str(), ios::binary ); if( !fout ) cout << "Die Datei konnte nicht zum Schreiben geöffnet werden!\n"; else { fout.write( ( char* )& Adressen[vorname], sizeof Adressen[vorname] ); // Adresse in eine eigene Datei schreiben } fout.close(); } void menuAuslesen( map<string, Adresse>& Adressen ) { int auswahl; cout << "Wollen sie nach Vorname suchen(1)\n"; cout << "Wollenn sie nach Nachname suchen(2)\n"; cin >> auswahl; if ( ( auswahl < 1 ) || ( auswahl > 2 ) ) { cout << "Falsche Eingabe!\n"; menuAuslesen( Adressen); } switch( auswahl ) { case 1: { auslesenVorname( Adressen ); // Öffnen der Funktion zum Auslesen bzw Suche per Vorname break; } /*case 2: { auslesenNachname( Adressen ); break; }*/ } } void auslesenVorname( map<string, Adresse>& Adressen ) { cout << "Geben sie den Vornamen ein den sie Suchen: "; string vorname; cin >> vorname; ifstream fin( vorname.c_str(), ios::binary ); if ( !fin ) cout << "Datei konnte nicht zum lesen geoeffnet werden!\n"; else { fin.read( ( char* )& Adressen[vorname], sizeof Adressen[vorname] ); cout << Adressen[vorname].getVorname() << "\n"; cout << Adressen[vorname].getNachname() << "\n"; cout << Adressen[vorname].getAdresse() << "\n"; cout << Adressen[vorname].getTele() << "\n"; cout << Adressen[vorname].getEmail() << "\n\n\n"; fin.close(); } }funktionen.h
#ifndef FUNKTIONEN_H_INCLUDED #define FUNKTIONEN_H_INCLUDED #include "classAdresse.h" #include <string> #include <map> #include <fstream> void menu( int& ); void adresseAnlegen( std::map<std::string, Adresse>& ); void menuAuslesen( std::map<std::string, Adresse>& ); void auslesenVorname( std::map<std::string, Adresse>& ); void auslesenNachname( std::map<std::string, Adresse>& ); #endif // FUNKTIONEN_H_INCLUDEDclassAdresse.cpp
#include <string> #include "classAdresse.h" using namespace std; Adresse::Adresse(std::string vorname, std::string nachname, std::string adresse, std::string tele, std::string email) : itsVorname( vorname ), itsNachname( nachname ), itsAdresse( adresse ), itsTele( tele ), itsEmail( email ) { } void Adresse::setVorname( string vorname ) { itsVorname = vorname; } void Adresse::setNachname( string nachname ) { itsNachname = nachname; } void Adresse::setAdresse( string adresse ) { itsAdresse = adresse; } void Adresse::setTele( string tele ) { itsTele = tele; } void Adresse::setEmail( string email ) { itsEmail = email; }classAdressen.h
#ifndef CLASSADRESSE_H_INCLUDED #define CLASSADRESSE_H_INCLUDED #include <string> class Adresse { public: Adresse(){} Adresse(std::string vorname, std::string nachname, std::string adresse, std::string tele, std::string email); ~Adresse(){} std::string getVorname() const { return itsVorname; } void setVorname( std::string vorname ); std::string getNachname() const { return itsNachname; } void setNachname( std::string nachname ); std::string getAdresse() const { return itsAdresse; } void setAdresse( std::string adresse ); std::string getTele() const { return itsTele; } void setTele( std::string tele ); std::string getEmail() const { return itsEmail; } void setEmail( std::string email ); private: std::string itsVorname; std::string itsNachname; std::string itsAdresse; std::string itsTele; std::string itsEmail; }; #endif // CLASSADRESSE_H_INCLUDEDHoffe das hilft zum helfen:D;-)
danke schonmal
-
So wie ich das sehe legst du die Adresse in adresseAnlegen() an, d.h. wenn du das Programm neustartest und adresseAnlegen() nicht ausführst wird die array Vorname nicht initalisiert und beim ausführen von read kommt es zur speicherverletzung.
EDIT: Hab jetzt das update gelesen und weis nicht wie es sich mit einem String verhält, dachte es würden char* verwendet...
-
mhh ok dann hoff ich mal dass jemand anders weiter weiß.
-
fr33g schrieb:
Aber sonst gehts noch

Solche Leute solltest du nicht beachten. Du hättest auch seiner Bitte mit dem Code nicht nachkommen müssen, schliesslich brauchst du hier niemandem was zu beweisen.
fr33g schrieb:
Also ich bin mit meinem Adressenbuch schon gut vorangekommen, jedoch häng ich jetzt fest.
Wenn ich das Programm schließe und wieder öffne und dann eine Adresse abfragen will, stürzt das Programm ab.Ich würde für den Anfang nicht binär, sondern im Textformat schreiben. Das ist nämlich einfacher und das kannst du auch besser debuggen (z.B. indem du mit dem Notepad nachschaust). Verwende hier also die Streamoperatoren und
std::getline()stattwrite()undread(). Du könntest zum Beispiel die einzelnen Eigenschaften einer Adresse mit ; trennen und die Adressen durch Newlines abgrenzen. Überleg dir einfach ein geeignetes Format.Im Weiteren würde ich hier nicht unbedingt eine
std::mapverwenden, da diese die Sortierung auf ein Kriterium beschränkt. Nimm lieber einenstd::vectorund richte dafür verschiedene Sortierkriterien ein, z.B.// 1. Möglichkeit: Funktor/Funktionsobjekt struct SortiereNachVornamen { bool operator() (const Adresse& lhs, const Adresse& rhs) const { return lhs.getVorname() < rhs.getVorname(); } }; // 2. Möglichkeit: Funktion bool SortiereNachVornamen(const Adresse& lhs, const Adresse& rhs) { return lhs.getVorname() < rhs.getVorname(); } // Anwendung: std::vector<Adresse> Adressen; std::sort(Adressen.begin(), Adressen.end(), SortiereNachVornamen()); // 1 std::sort(Adressen.begin(), Adressen.end(), &SortiereNachVornamen); // 2Ausserdem könntest du ein
typedeffür deinen Adressen-Container einrichten, um nicht immer den vollen Namen tippen zu müssen. Das hat auch den Vorteil, dass du leicht den Containertypen auswechseln kannst, ohne die Implementierung ändern zu müssen.typedef std::vector<Adresse> AdressenContainer;Ansonsten siehts schon recht gut aus, du bist auf dem richtigen Weg!
-
Erst mal Danke für deine Hilfe

Also habs jetzt ohne binär gemacht einfach in eine Datei und mir ein Format überlegt und es klappt=)
Muss jetzt nur noch anstatt map nen vector nehmen und das ganze dann Erweitern für die Sortierfunktion.Hab jedoch noch ne Frage, gibt es eine Funktion, dass ich um eine Zeile zurücksprigen kann?
Denn wenn ich nach dem Nachname such und er ihn findet, soll ja die komplette Adresse plus Vorname ausgegeben werden, und der Vorname steht ja logischerweise vor dem Nachname:-P
-
fr33g schrieb:
Hab jedoch noch ne Frage, gibt es eine Funktion, dass ich um eine Zeile zurücksprigen kann?
Denn wenn ich nach dem Nachname such und er ihn findet, soll ja die komplette Adresse plus Vorname ausgegeben werden, und der Vorname steht ja logischerweise vor dem Nachname:-PIch würde sowieso den kompletten Datensatz laden, damit du z.B. auch alle Einträge anzeigen oder gleich wieder gemeinsam speichern kannst. Sollte kein Speicherproblem sein bei ein paar Adressen.
-
Ja klar mach ich doch auch, wenn ich richtig verstanden hab was du meinst.
Aber ich muss ja wenn er den nachname gefunden hat nicht ab da auslesen sondern, "ab eine zeile vorher".
verstehst du was ich mein?
-
Ich würde einen Eintrag nicht auszulesen beginnen, wenn du auf den Nachnamen triffst, sondern z.B. jede Zeile einlesen und parsen (unterschiedliche Eigenschaften durch irgendein Trennzeichen wie ";" trennen).
Also mit
std::getline()die Zeile in einen String einlesen und da zerpflücken. Es gäbe aber auch elegantere Möglichkeiten wie Boost.Tokenizer, aber ich weiss nicht, ob du dich jetzt damit auseinandersetzen willst. Es ist ja eigentlich nicht sehr schwierig, selbst die Tokens herauszulesen. Mitstd::string::find()undstd::string::substr()sollte das gehen.
-
Also irgendwie häng ich jetzt:
main.cpp
#include <iostream> #include <string> #include <map> #include <fstream> #include "classAdresse.h" #include "funktionen.h" using namespace std; int main() { bool stop = false; int auswahl; map<string, Adresse> Adressen; while( !stop ) { menu(auswahl); switch( auswahl ) { case 1: { adresseAnlegen( Adressen ); break; } case 2: { menuAuslesen( Adressen ); break; } case 3: { cout << "Programm wird beendet!"; stop = true; break; } } } }classAdresse.h
#ifndef CLASSADRESSE_H_INCLUDED #define CLASSADRESSE_H_INCLUDED #include <string> class Adresse { public: Adresse(){} Adresse(std::string vorname, std::string nachname, std::string adresse, std::string tele, std::string email); ~Adresse(){} std::string getVorname() const { return itsVorname; } void setVorname( std::string vorname ); std::string getNachname() const { return itsNachname; } void setNachname( std::string nachname ); std::string getAdresse() const { return itsAdresse; } void setAdresse( std::string adresse ); std::string getTele() const { return itsTele; } void setTele( std::string tele ); std::string getEmail() const { return itsEmail; } void setEmail( std::string email ); private: std::string itsVorname; std::string itsNachname; std::string itsAdresse; std::string itsTele; std::string itsEmail; }; #endif // CLASSADRESSE_H_INCLUDEDclassAdresse.cpp
#include <string> #include "classAdresse.h" using namespace std; Adresse::Adresse(std::string vorname, std::string nachname, std::string adresse, std::string tele, std::string email) : itsVorname( vorname ), itsNachname( nachname ), itsAdresse( adresse ), itsTele( tele ), itsEmail( email ) { } void Adresse::setVorname( string vorname ) { itsVorname = vorname; } void Adresse::setNachname( string nachname ) { itsNachname = nachname; } void Adresse::setAdresse( string adresse ) { itsAdresse = adresse; } void Adresse::setTele( string tele ) { itsTele = tele; } void Adresse::setEmail( string email ) { itsEmail = email; }funktionen.h
#ifndef FUNKTIONEN_H_INCLUDED #define FUNKTIONEN_H_INCLUDED #include "classAdresse.h" #include <string> #include <map> #include <fstream> void menu( int& ); void adresseAnlegen( std::map<std::string, Adresse>& ); void menuAuslesen( std::map<std::string, Adresse>& ); void auslesenVorname( std::map<std::string, Adresse>& ); void auslesenNachname( std::map<std::string, Adresse>& ); #endif // FUNKTIONEN_H_INCLUDEDfunktionen.cpp
#include "classAdresse.h" #include "funktionen.h" #include <iostream> #include <string> #include <map> #include <fstream> using namespace std; void menu( int& auswahl ) { cout << "Was wollen sie tun:\n"; cout << "Neue Adresse anlegen(1)\n"; cout << "Adresse suchen(2)\n"; cout << "Programm beenden(3)\n"; cin >> auswahl; if( ( auswahl < 1 ) || ( auswahl > 3 ) ) { cout << "Falsche Eingabe!\n"; menu(auswahl); } } void adresseAnlegen( map<string, Adresse>& Adressen ) { cout << "Geben sie den Vornamen ein: "; string vorname; cin >> vorname; cout << "Geben sie den Nachnamen ein: "; string nachname; cin >> nachname; cout << "Geben sie die Adresse ein: "; string adresse; cin.ignore(); getline( cin, adresse ); cout << "Geben sie die Telefonnummer ein: "; string tele; cin >> tele; cout << "Geben sie die Email-Adresse ein: "; string email; cin>> email; Adressen[vorname] = Adresse(vorname, nachname, adresse, tele, email); // Adresse wird erstellt in der map ofstream fout( "Adressen.txt", ios::app ); if( !fout ) cout << "Die Datei konnte nicht zum Schreiben geöffnet werden!\n"; else { fout << Adressen[vorname].getVorname() << "\n"; fout << Adressen[vorname].getNachname() << "\n"; fout << Adressen[vorname].getAdresse() << "\n"; fout << Adressen[vorname].getTele() << "\n"; fout << Adressen[vorname].getEmail() << "\n\n\n"; } fout.close(); } void menuAuslesen( map<string, Adresse>& Adressen ) { int auswahl; cout << "Wollen sie nach Vorname suchen(1)\n"; cout << "Wollenn sie nach Nachname suchen(2)\n"; cin >> auswahl; if ( ( auswahl < 1 ) || ( auswahl > 2 ) ) { cout << "Falsche Eingabe!\n"; menuAuslesen( Adressen ); } switch( auswahl ) { case 1: { auslesenVorname( Adressen ); // Öffnen der Funktion zum Auslesen bzw Suche per Vorname break; } /*case 2: { auslesenNachname( Adressen ); break; }*/ } } void auslesenVorname( map<string, Adresse>& Adressen ) { cout << "Geben sie den Vornamen ein den sie Suchen: "; string vorname; cin >> vorname; ifstream fin( "Adressen.txt", ios::in ); if ( !fin ) cout << "Datei konnte nicht zum lesen geoeffnet werden!\n"; else { string temp; while( getline( fin, temp) ) { if( temp == vorname ) { Adressen[vorname].setVorname( temp ); getline( fin, temp ); Adressen[vorname].setNachname( temp ); getline( fin, temp ); Adressen[vorname].setAdresse( temp ); getline( fin, temp ); Adressen[vorname].setTele( temp ); getline( fin, temp ); Adressen[vorname].setEmail( temp ); } } cout << "\n"; cout << Adressen[vorname].getVorname() << "\n"; cout << Adressen[vorname].getNachname() << "\n"; cout << Adressen[vorname].getAdresse() << "\n"; cout << Adressen[vorname].getTele() << "\n"; cout << Adressen[vorname].getEmail() << "\n\n\n"; } fin.close(); }ICh häng jetzt irgendwie fest, alles in nen vector ändern, wollt ich eg erst wenns mit map läuft.
Mein Problem, ich weiß nicht genau wie ich das machen soll, falls es ne Adresse also den Vornamen 2 mal gibt.
Hatte da was probiert, jedes mal nach dem anzeigen den benutzer fragen ob das die richtige ist, wenn er nein sagte wurde mir jedoch immer wieder die gleiche angezeigt, und nicht die nächste mit dem gleichen vornamen. sprich ich weiß net wie ichs umsetzen soll.
Hab das Gefühl der ließt die Datei immer wieder von da weiter wo er aufgehört hat.
Ich würds eg gern so machen, wenn er die funktion vornameauslesen verlässt, soll er von vorne anfangen auszulesen.
Wenn ich dann was eingebaut hab dass er weiterließt wenn es nicht die richtige Adresse ist, soll er logischerweise dort weitermachen wo er aufhörte, um die nächste adresse zu finden.Hoffe ihr könnt mir nochmal helfen das umzusetzen;-)
EDIT:
Also habe es hinbekommen, bin auf einmal grad draufgekommen:D so ähnlich hatte ich es eg auch schon:-PIch setzt mal die neue funktionen.cpp rein
#include "classAdresse.h" #include "funktionen.h" #include <iostream> #include <string> #include <map> #include <fstream> using namespace std; void menu( int& auswahl ) { cout << "Was wollen sie tun:\n"; cout << "Neue Adresse anlegen(1)\n"; cout << "Adresse suchen(2)\n"; cout << "Programm beenden(3)\n"; cin >> auswahl; if( ( auswahl < 1 ) || ( auswahl > 3 ) ) { cout << "Falsche Eingabe!\n"; menu(auswahl); } } void adresseAnlegen( map<string, Adresse>& Adressen ) { cout << "Geben sie den Vornamen ein: "; string vorname; cin >> vorname; cout << "Geben sie den Nachnamen ein: "; string nachname; cin >> nachname; cout << "Geben sie die Adresse ein: "; string adresse; cin.ignore(); getline( cin, adresse ); cout << "Geben sie die Telefonnummer ein: "; string tele; cin >> tele; cout << "Geben sie die Email-Adresse ein: "; string email; cin>> email; Adressen[vorname] = Adresse(vorname, nachname, adresse, tele, email); // Adresse wird erstellt in der map ofstream fout( "Adressen.txt", ios::app ); if( !fout ) cout << "Die Datei konnte nicht zum Schreiben geöffnet werden!\n"; else { fout << Adressen[vorname].getVorname() << "\n"; fout << Adressen[vorname].getNachname() << "\n"; fout << Adressen[vorname].getAdresse() << "\n"; fout << Adressen[vorname].getTele() << "\n"; fout << Adressen[vorname].getEmail() << "\n\n\n"; } fout.close(); } void menuAuslesen( map<string, Adresse>& Adressen ) { int auswahl; cout << "Wollen sie nach Vorname suchen(1)\n"; cout << "Wollenn sie nach Nachname suchen(2)\n"; cin >> auswahl; if ( ( auswahl < 1 ) || ( auswahl > 2 ) ) { cout << "Falsche Eingabe!\n"; menuAuslesen( Adressen ); } switch( auswahl ) { case 1: { auslesenVorname( Adressen ); // Öffnen der Funktion zum Auslesen bzw Suche per Vorname break; } /*case 2: { auslesenNachname( Adressen ); break; }*/ } } void auslesenVorname( map<string, Adresse>& Adressen ) { cout << "Geben sie den Vornamen ein den sie Suchen: "; string vorname; cin >> vorname; ifstream fin( "Adressen.txt", ios::in ); if ( !fin ) cout << "Datei konnte nicht zum lesen geoeffnet werden!\n"; else { string temp; while( getline( fin, temp ) ) { if( temp == vorname ) { Adressen[vorname].setVorname( temp ); getline( fin, temp ); Adressen[vorname].setNachname( temp ); getline( fin, temp ); Adressen[vorname].setAdresse( temp ); getline( fin, temp ); Adressen[vorname].setTele( temp ); getline( fin, temp ); Adressen[vorname].setEmail( temp ); cout << "\n"; cout << Adressen[vorname].getVorname() << "\n"; cout << Adressen[vorname].getNachname() << "\n"; cout << Adressen[vorname].getAdresse() << "\n"; cout << Adressen[vorname].getTele() << "\n"; cout << Adressen[vorname].getEmail() << "\n\n\n"; cout << "War dies die richtige Adresse(1) oder nicht(2): "; int auswahl; cin >> auswahl; if( auswahl == 1 ) break; else if( auswahl == 2 ) { continue; } else if( ( auswahl < 1 ) || ( auswahl > 2 ) ) { cout << "Falsche Eingabe\n"; auslesenVorname( Adressen ); } } } } fin.close(); }Dann mach ich mich jetzt mal an die Suche per Nachname=)
-
Hey Leute, bin jetzt eg fast fertig, blos bei der Funktion sortiert Ausgeben, hängts noch, es stürzt zwar nicht ab, gibt jedoch nur leere zeilen aus, hier mal der verantwortliche Code:
void sortiertAusgeben() { ifstream fin( "Adressen.txt", ios::in ); if ( !fin ) cout << "Datei konnte nich zum lesen geöffnet werden!\n"; else { int i = 0; char temp; string free; string vorname; string nachname; string adresse; string tele; string email; while (fin.get( temp ) ) { if( temp == '_' ) ++i; } fin.close(); vector<Adresse> Adressen( i ); fin.open( "Adressen.txt", ios::in ); for( int j = 0; j < i; ++j ) { getline( fin, vorname ); getline( fin, nachname ); getline( fin, adresse ); getline( fin, tele ); getline( fin, email ); Adressen[j] = Adresse( vorname, nachname, adresse, tele, email ); getline( fin, free ); getline( fin, free ); } fin.close(); sort( Adressen.begin(), Adressen.end(), sortiereNachVornamen() ); for( int j = 0; j < i; ++j ) { cout << Adressen[j].getVorname() << "\n"; cout << Adressen[j].getNachname() << "\n"; cout << Adressen[j].getAdresse() << "\n"; cout << Adressen[j].getTele() << "\n"; cout << Adressen[j].getEmail() << "\n\n\n"; } } }Hoffe ihr könnt mir helfen=)