Struct in die Funktion übergeben



  • Hallo.
    Ich habe ein Struct gebaut mit nen paar Attributen/Variabeln.

    Ich möchte nun ein Funktion basteln und den Struct dadrinne benutzen.
    Bekomme es aber nicht ganz hin.
    Wollte es eigentlich ganz normal übern Parameter übergeben.

    Hier mein Code:

    #include "stdafx.h"
    #include <iostream>
    #include <conio.h>
    #include <string>
    
    using namespace std;
    
    void DatenAendern (struct PersonTyp Person1)
    {	
    	PersonTyp *Editperson = 0;
    	Editperson = &Person1;
    	Editperson->iAlter = 12;
    }
    
    int main()
    {
    	struct PersonTyp
    	{
    		string sName;
    		string sWohnort;
    		int iAlter;
    		string sTelefon;
    		string sEmail;		
    	};
    
    	struct PersonTyp Person1 = {"Peter", "Hamburg", 34, "0465/87521", "Peter.G@gmx.de"};
    	struct PersonTyp Person2 = {"Hans", "Berlin", 58, "0171/1549852", "Hans-Berlin@gmx.net"};
    
    	DatenAendern(Person1);
    
    	cout << "\nDein Name ist:     \t"<<Person1.sName<<endl;
    	cout << "Dein Wohnort ist: \t"<<Person1.sWohnort<<endl;
    	cout << "Dein Alter ist: \t"<<Person1.iAlter<<endl;
    	cout << "Deine Telefonnr ist: \t"<<Person1.sTelefon<<endl;
    	cout << "Dein Email ist: \t"<<Person1.sEmail<<endl;
    	cout << endl;
    
    	cout << "\nDein Name ist:     \t"<<Person2.sName<<endl;
    	cout << "Dein Wohnort ist: \t"<<Person2.sWohnort<<endl;
    	cout << "Dein Alter ist: \t"<<Person2.iAlter<<endl;
    	cout << "Deine Telefonnr ist: \t"<<Person2.sTelefon<<endl;
    	cout << "Dein Email ist: \t"<<Person2.sEmail<<endl;
    	cout << endl;
    
     getch();
        return 0;
    }
    

    edit pumuckl: [b]-Tags aus dem Code entfernt



  • Du musst dein struct vor der Funktion definieren (nicht in der main!), sonst ist es dort gar nicht bekannt. In Zukunft solltest du die Fehlermeldungen direkt mitposten, dann kann man dir auch schneller helfen.



  • _matze schrieb:

    Du musst dein struct vor der Funktion definieren (nicht in der main!), sonst ist es dort gar nicht bekannt. In Zukunft solltest du die Fehlermeldungen direkt mitposten, dann kann man dir auch schneller helfen.

    Danke für die Antwort.
    Habs mal geändert.

    Er zeigt keine Fehler an aber ändern (siehe Funktion DatenAendern() ) hat er es trotzdem nicht.

    #include "stdafx.h"
    #include <iostream>
    #include <conio.h>
    #include <string>
    
    using namespace std;
    
    struct PersonTyp
    {
    	string sName;
    	string sWohnort;
    	int iAlter;
    	string sTelefon;
    	string sEmail;		
    };
    
    void DatenAendern (struct PersonTyp Person1)
    {	
    	PersonTyp *Editperson = 0;
    	Editperson = &Person1;
    	Editperson->iAlter = 1222;
    }
    
    int main()
    {
    
    	struct PersonTyp Person1 = {"Peter", "Hamburg", 34, "0465/87521", "Peter.G@gmx.de"};
    	struct PersonTyp Person2 = {"Hans", "Berlin", 58, "0171/1549852", "Hans-Berlin@gmx.net"};
    
    	DatenAendern(Person1);
    
    	cout << "\nDein Name ist:     \t"<<Person1.sName<<endl;
    	cout << "Dein Wohnort ist: \t"<<Person1.sWohnort<<endl;
    	cout << "Dein Alter ist: \t"<<Person1.iAlter<<endl;
    	cout << "Deine Telefonnr ist: \t"<<Person1.sTelefon<<endl;
    	cout << "Dein Email ist: \t"<<Person1.sEmail<<endl;
    	cout << endl;
    
    	cout << "\nDein Name ist:     \t"<<Person2.sName<<endl;
    	cout << "Dein Wohnort ist: \t"<<Person2.sWohnort<<endl;
    	cout << "Dein Alter ist: \t"<<Person2.iAlter<<endl;
    	cout << "Deine Telefonnr ist: \t"<<Person2.sTelefon<<endl;
    	cout << "Dein Email ist: \t"<<Person2.sEmail<<endl;
    	cout << endl;
    
     	getch();
        return 0;
    }
    


  • Das liegt nun daran, dass Du das Objekt tatsächlich "in die Funktion" übergibst. Sprich, die Funktion legt eine lokale Kopie der Struktur an, die Du dann veränderst. Das Objekt, das Du beim Aufruf angegeben hast, bleibt unangetastet.

    Du müsstest also eine Referenz (&) oder einen Zeiger auf die Struktur an die Funktion übergeben. Besser ist natürlich eine Referenz.

    BTW: Warum legst Du in der Funktion nochmal einen redundanten Zeiger an, der auf das gleiche Objekt zeigt?

    BTW2: In C++ ist es unüblich Objekte mit struct Person objekt zu definieren. Das ist ein Relikt aus C-Zeiten. Schreib stattdessen einfach Person objekt .



  • LordJaxom schrieb:

    Das liegt nun daran, dass Du das Objekt tatsächlich "in die Funktion" übergibst. Sprich, die Funktion legt eine lokale Kopie der Struktur an, die Du dann veränderst. Das Objekt, das Du beim Aufruf angegeben hast, bleibt unangetastet.

    Du müsstest also eine Referenz (&) oder einen Zeiger auf die Struktur an die Funktion übergeben. Besser ist natürlich eine Referenz.

    BTW: Warum legst Du in der Funktion nochmal einen redundanten Zeiger an, der auf das gleiche Objekt zeigt?

    BTW2: In C++ ist es unüblich Objekte mit struct Person objekt zu definieren. Das ist ein Relikt aus C-Zeiten. Schreib stattdessen einfach Person objekt .

    Nun gehts.
    Habs wiefolgt geändert:

    void DatenAendern (struct PersonTyp *Person)
    {	
    	PersonTyp *Editperson = 0;
    	Editperson = Person;
    	Editperson->iAlter = 25;
    }
    
    int main()
    {
    
    	struct PersonTyp Person1 = {"Peter", "Hamburg", 34, "0465/87521", "Peter.G@gmx.de"};
    	struct PersonTyp Person2 = {"Hans", "Berlin", 58, "0171/1549852", "Hans-Berlin@gmx.net"};
    
    	DatenAendern(&Person1);
    
    //etc.....
    

    BTW: Warum legst Du in der Funktion nochmal einen redundanten Zeiger an, der auf das gleiche Objekt zeigt?

    BTW2: In C++ ist es unüblich Objekte mit struct Person objekt zu definieren. Das ist ein Relikt aus C-Zeiten. Schreib stattdessen einfach Person objekt .

    Wie genau meinst du das?

    Mfg



  • Warum schreibst du nicht einfach kurz und knapp

    void DatenAendern (PersonTyp *person) 
    {    
        person->iAlter = 25; 
    }
    

    ?

    Warum also benutzt du noch (sehr umständlich) die Variable 'Editperson'???

    Und als Ergänzung:
    Mit Referenzen ist es noch schicker:

    struct Person // lass 'Typ' mal weg
    {
        string sName;
        string sWohnort;
        int iAlter;
        string sTelefon;
        string sEmail;        
    };
    
    void DatenAendern(Person &person) // & bedeutet Referenz
    {
       person.iAlter = 42; // Zugriff mittels des Punktes anstatt erst zu dereferenzieren (->, bzw. (*).)
    }
    

    Aber du scheinst noch ein Buch/Tutorial durchzuarbeiten, oder?



  • Th69 schrieb:

    Warum schreibst du nicht einfach kurz und knapp

    void DatenAendern (PersonTyp *person) 
    {    
        person->iAlter = 25; 
    }
    

    ?

    Warum also benutzt du noch (sehr umständlich) die Variable 'Editperson'???

    Und als Ergänzung:
    Mit Referenzen ist es noch schicker:

    struct Person // lass 'Typ' mal weg
    {
        string sName;
        string sWohnort;
        int iAlter;
        string sTelefon;
        string sEmail;        
    };
    
    void DatenAendern(Person &person) // & bedeutet Referenz
    {
       person.iAlter = 42; // Zugriff mittels des Punktes anstatt erst zu dereferenzieren (->, bzw. (*).)
    }
    

    Aber du scheinst noch ein Buch/Tutorial durchzuarbeiten, oder?

    Danke. Habs nun so umgeändert. 😉
    So spart man sich Platz.^^

    Noch ne Frage:

    Hier meine FUnktion:

    void DatenAendern (PersonTyp &Person)
    {	
    	cout << "Daten \x84ndern:\n"<<endl;
    
    	cout << "Name: ";
    	getline(cin,Person.sName);
    
    	cout << "Wohnort: ";
    	getline(cin,Person.sWohnort);
    
    	cout << "Alter: ";
    	cin >> Person.iAlter;
    
    	cout << "Telefon: ";
    	getline(cin,Person.sTelefon);
    
    	cout << "E-Mail: ";
    	getline(cin,Person.sEmail);
    
    }
    

    Er fragt alles wunderbar ab ABER sobald er mit

    cout << "Alter: ";
    	cin >> Person.iAlter;
    

    fertig ist, überspringt er
    die "Telefon" und macht bei "E-Mail" weiter.
    Warum?

    Das liegt am cin.!
    Wenn ich daraus ein String mache und es wie bei den anderen abfrage, läufts wunderbar.
    Aber bei cin >>
    überspringt er eine Abfrage



  • Klaus - wer sonst? schrieb:

    Er fragt alles wunderbar ab ABER sobald er mit

    cout << "Alter: ";
    	cin >> Person.iAlter;
    

    fertig ist, überspringt er
    die "Telefon" und macht bei "E-Mail" weiter.
    Warum?

    Das liegt am cin.!
    Wenn ich daraus ein String mache und es wie bei den anderen abfrage, läufts wunderbar.
    Aber bei cin >>
    überspringt er eine Abfrage

    Wenn du bei Alter mehr als nur die eine Zahl schreibst, liest er trotzdem nur die eine Zahl ein. Danach ist allerdings noch etwas im Stream, und das wird beim nächsten getline() in den String geschrieben, ohne dass du noch eine Eingabe machen musst.



  • Ehm ok.!?
    Und wie umgehe ich das?
    Versteh deine Aussage nicht ganz, dazu fehlt mir leider die Routine.



  • Du musst den Stream von eventuellen Fail-Flags befreien, danach ignorierst du den übrigen Eingabepuffer und zwar mit exakt mit der Größe, die noch drin liegt, also so:

    cin.clear(); // Fehler-Flags löschen
    cin.ignore(cin.rdbuf()->in_avail()); // Die im Puffer noch anstehenden Zeichen ignorieren
    

  • Mod

    Ad aCTa schrieb:

    Du musst den Stream von eventuellen Fail-Flags befreien, danach ignorierst du den übrigen Eingabepuffer und zwar mit exakt mit der Größe, die noch drin liegt, also so:

    cin.clear(); // Fehler-Flags löschen
    cin.ignore(cin.rdbuf()->in_avail()); // Die im Puffer noch anstehenden Zeichen ignorieren
    

    Das ist keine gute Idee, denn das macht nur Sinn, wenn deine Standardeingabe von einer Tastatur kommt. Wenn deine Standardeingabe aber irgendwas anderes ist, ignorierst du somit alles was noch kommt. Das eigentliche Problem ist hier ja, dass cin >> int eben nur einen int einliest. Sind die Werte in der Eingabe durch newlines getrennt, so bleibt danach das newline-Zeichen im Puffer und das nächste getline liest dann genau bis zu diesem newline -> es wird nichts eingelesen.

    Dagegen hilft es ganz einfach, das nächste newline zu ignorieren:

    cin.ignore(2,'\n');
    

    Dann funktioniert die Eingabe aus beliebigen Quellen, die einzelnen Werte müssen bloß durch newlines getrennt sein.

    Ich habe jetzt oben sicherheitshalber eine 2 geschrieben, da ich nicht weiß, wie sich das mit Windows newlines verhält, wo newlines ja 2 Zeichen sind und ich kann das jetzt auch nicht testen. Unter Posix Systemen reicht jedenfalls auch eine 1.


Log in to reply