struct mit char[] einlesen



  • Hallo,

    folgendes Programm lässt sich ganz normal kompilieren.
    sobald ich es aber ausführe, bricht es nach Eingabe meiner Werte mit einem Fehler ab; beim Fehler steht jedoch keine Fehlerbeschreibung; nur

    AppName: main.exe AppVer: 0.0.0.0 ModName: msvcrt.dll
    ModVer: 7.0.2600.5512 Offset: 000360c1

    so: hier mein Programm:

    #include <iostream>
    using namespace std;
    
    struct Person
    {
    	char vorname[30];
    	char nachname[30];
    };
    
    Person* neue_person(char vorname[30], char nachname[30])
    {
    	Person* p;
    	strcpy(p->vorname, vorname);
    	strcpy(p->nachname, nachname);
    	return p;
    }
    
    Person* person_einlesen()
    {
    	char vorname[30];
    	char nachname[30];
    	cout << "Vorname: ";
    	cin >> vorname;
    	cout << "Nachname: ";
    	cin >> nachname;
    	Person* p = neue_person(vorname, nachname);
    	return p;
    }
    
    void person_ausgeben(Person* p)
    {
    	printf("person_ausgeben():\n");
    	printf("%s\n", p->vorname);
    	printf("%s\n", p->nachname);
    }
    
    int main()
    {
    	struct Person* p = person_einlesen();
    	person_ausgeben(p);
    }
    

    weiß irgendwer, wie ich das umschreiben muss, damit es funktioniert?

    lg, guni



  • #include <iostream> 
    using namespace std; 
    
    struct Person 
    { 
        char vorname[30]; // Lieber std::string
        char nachname[30]; // Dito
    }; 
    
    Person* neue_person(char *vorname, char *nachname) 
    { 
        Person p; // Zeiger ist hier unnötig
        strcpy(p.vorname, vorname); 
        strcpy(p.nachname, nachname); 
    
        return &p; 
    } 
    
    Person* person_einlesen() 
    { 
        char vorname[30]; 
        char nachname[30]; 
    
        cout << "Vorname: "; 
        cin >> vorname; 
        cout << "Nachname: "; 
        cin >> nachname; 
    
        Person* p = neue_person(vorname, nachname); 
    
        return p; 
    } 
    
    void person_ausgeben(Person p) 
    { 
    	std::cout<< "person_ausgeben():" <<std::endl; // Bitte kein printf
    
    	std::cout<< p.vorname <<std::endl;
    	std::cout<< p.nachname <<std::endl;
    } 
    
    int main() 
    { 
        Person* p = person_einlesen(); 
    
        person_ausgeben(*p); 
    
    	std::cin.get();
    }
    


  • Person* neue_person(char vorname[30], char nachname[30])
    {
        Person* p;
        strcpy(p->vorname, vorname);
        strcpy(p->nachname, nachname);
        return p;
    }
    

    Hier liegt der Hund begraben. Du erzeugst einen Zeiger auf eine Person, der auf nichts zeigt. Du hast kein Objekt konstruiert!
    --> Person *p = new Person;
    Und schon sieht die Welt wieder heile aus. Vergiss nicht, das Objekt mit delete zu zerstören!



  • @ Kóyaánasqatsi

    Person* neue_person(char *vorname, char *nachname)
    {
        Person p; // Zeiger ist hier unnötig
        strcpy(p.vorname, vorname);
        strcpy(p.nachname, nachname);
    
        return &p;
    }
    

    Der Zeiger ist sehr wohl nötig, da das Objekt p nach dem Verlassen von neue_person zerstört werden würde. oO

    @TE
    Verbesserte Version deines Programmes:

    #include <iostream>
    using namespace std;
    
    struct Person
    {
        Person(string vor, string nach)
         : vorname(vor), nachname(nach)
        {}
    
        string vorname;
        string nachname
    };
    
    Person* neue_person(string vorname, string nachname)
    {
        Person *p = new Person(vorname, nachname);
        return p;
    }
    
    Person* person_einlesen()
    {
        char vorname[30];
        char nachname[30];
    
        cout << "Vorname: ";
        cin >> vorname;
        cout << "Nachname: ";
        cin >> nachname;
    
        Person* p = neue_person(vorname, nachname);
        return p;
    }
    
    void person_ausgeben(Person p)
    {
        std::cout<< "person_ausgeben():" <<std::endl;
    
        std::cout<< p.vorname <<std::endl;
        std::cout<< p.nachname <<std::endl;
    }
    
    int main()
    {
        Person* p = person_einlesen();
    
        person_ausgeben(*p);
    
        std::cin.get();
        delete p;
    }
    

    rya.



  • Wenn du C++ programmierst, dann verwende doch bitte die sprachlichen Mittel, die dir diese Sprache zur Verfuegung stellt. Hier ist es std::string.



  • hi leute,

    danke für eure ausführlichen antworten!
    das problem ist, dass ich in c nachhilfe geb (eigentlich programmier ich eher java und perl) und mein schüler nimmt zwar sehr wohl einen c++ compiler her, sie lernen aber im unterricht noch keine oop; d.h. ich bin mit dem nutzen der sprache zur zeit noch etwas gebunden.

    wie auch immer - jedenfalls danke für eure ratschläge ...



  • guni schrieb:

    dass ich in c nachhilfe geb

    Darf man wissen, wieso du nachhilfe in etwas gibst das du nicht beherrscht? Naja, jedem das seine...



  • ich beherrsche das programmieren.
    die sprache ist ja grundsätzlich egal wenn man jetzt mal von irgendwelchen esotersichen programmiersprachen absieht.

    und c hab ich in der vergangenheit auch schon mal ein bisschen was gemacht.
    grundsätzlich wird in der klasse c auf einem niveau unterrichtet, dass ich mir auch noch zutrau; es gibt halt immer wieder situationen, in denen wir kurz mal googeln müssen.

    die aktuelle aufgabenstellung ist aus der situation heraus gekommen; die klasse ist noch lange nicht so weit, dass sie sich mit pointern auseinandersetzt; das war eine von mir erfundene aufgabenstellung.

    frage beantwortet? 😃
    also ... nochmals danke für eure hilfe.

    und - bezugnehmend auf den nickname desjenigen, der hier zuletzt geantwortet hat: ob jesus schwarz war wage ich mal in frage zu stellen, nachdem er israelit war 😉



  • jetzt steh ich schon wieder auf der leitung.
    um meine struct aus einer datei auslesen zu können müssen die daten ja eine fixlänge haben ...

    also hab ich mir so eine fillup-funktion geschrieben;

    char* auffuellen(char* text, int gesamtlaenge)
    {
    	char* ret;
    	strcpy(ret, text);
    	for (int i = sizeof(text)+1; i<gesamtlaenge; i++) {
    		ret[i] = ' ';
    	}
    	ret[gesamtlaenge] = '\0';
    	return ret;
    }
    
    void person_speichern(char* filename, Person* p)
    {
    	char* c = auffuellen(p->vorname, 10);
    	FILE* fp = fopen(filename, "w");
    	fprintf(fp, p->vorname);
    	fprintf(fp, p->nachname);
    	fclose(fp);
    }
    
    int main()
    {
    	struct Person* p = person_einlesen();
    	person_speichern("personen.dat", p);
    
    	char* b = "test";
    	char* c = auffuellen(p->vorname, 10);
    	cout << c << ".";
    }
    

    das komische is: sie funktioniert in der main, in der person_speichern bekomm ich allerdings einen fehler ...

    weiß da noch irgendwer weiter?!

    ps.: ich weiß, dass ich so einen fillup theoretisch mit irgendeinem sprintf oder sowas auch lösen könnte; aber ein paar funktionen dazu sind eine ganz nette übung 😉



  • ... aber eigentlich ist das ja eine andere frage.
    ich werd dazu ein neues thema aufmachen.

    wie kann ich denn diesen thread hier als erledigt markieren?!



  • guni schrieb:

    jetzt steh ich schon wieder auf der leitung.
    um meine struct aus einer datei auslesen zu können müssen die daten ja eine fixlänge haben ...

    also hab ich mir so eine fillup-funktion geschrieben;

    char* auffuellen(char* text, int gesamtlaenge)
    {
    	char* ret;         //<---| Wie genau stellst du dir das hier vor??
    	strcpy(ret, text); //<---|
    	for (int i = sizeof(text)+1; i<gesamtlaenge; i++) {
    		ret[i] = ' ';
    	}
    	ret[gesamtlaenge] = '\0';
    	return ret;
    }
    

    Tut mir leid aber ich kann beim besten willen nicht erkennen, dass du C geschweige denn C++ beherrscht. Stichwort: wilder Zeiger.
    Du musst schon Speicher reservieren.
    Aber ich verstehe sowieso nicht, warum die dir das Leben so unnötig kompliziert machst und Zeiger zurück gibts?
    Warum keine Kopien über den Stack, so wie es viel sinnvoller wäre.

    Gate



  • ich kann mich auch nicht erinnern, jemals behauptet zu haben, dass ich c oder c++ beherrsche.
    ich habe geschrieben, dass ich das Programmieren beherrsche; nicht c.
    weder perl noch java fordert, dass ich speicher reserviere!
    stimmt - dieses Konzept ist neu für mich.

    Zeiger find ich auch grundsätzlich sehr unkompliziert (zumindest sind sie das in Perl für mich ...)

    und was für eine Alternative hab ich denn um in c einen String beliebiger Länge zurückzugeben?

    mfg, guni


Anmelden zum Antworten