struct array funktion übergeben



  • Ich würde gerne einen Struct Array eine Funktion geben. (Natürlich mit Referenz)
    Hier mein Code bisher:

    main.cpp

    void create_user(data &*user); //Hier ist "Line 6"
    
    int main(){
        struct data{
            string username;
            string password;
        };
    
        data user[19];
        create_user(user, 19);
    
        cout << user[0].username << "-------" << user[0].password;
        return 0;
    }
    
    void create_user(data &*user){
        user[0].username="Horst";
        user[0].password="B4um";
    }
    

    Und ich bekomme die Fehler:
    Variable oder Feld "create_user" als "void" deklariert <- Line6
    "data" wurde in diesem Gültigkeitsbereich nicht deklariert & "user" auch nicht <- Line6
    Und in der Funktion kennt er die "struct-Elemte" auch nicht.

    Bitte helft mir.


  • Mod

    void create_user(data &*user); //Hier ist "Line 6"
    

    Du hast data zu diesem Zeitpunkt nicht deklariert. Daher beschwert sich der Compiler (zu Recht).

    So sollte es aussehen:

    #include <iostream>
    #include <string>
    #include <vector>
    
    struct data
    {
    	std::string username;
    	std::string password;
    
    	data( std::string const& username,
    	      std::string const& password ) :
    		username(username),
    		password(password) {}
    };
    
    int main()
    {
    	std::vector<data> users;
    	users.emplace_back( "Horst", "B4um" );
    
    	std::cout << users.front().username << "-------" << users.front().password;
    }
    


  • Abgesehen davon, dass du hier keine Referenz auf einen Zeiger brauchst, schreibt man das data *& user . Was du geschrieben hast heißt "Zeiger auf Referenz", und sowas gibt es nicht.



  • Arcoth schrieb:

    void create_user(data &*user); //Hier ist "Line 6"
    

    Du hast data zu diesem Zeitpunkt nicht deklariert. Daher beschwert sich der Compiler (zu Recht).

    So sollte es aussehen:

    #include <iostream>
    #include <string>
    #include <vector>
    
    struct data
    {
    	std::string username;
    	std::string password;
    
    	data( std::string const& username, std::string const& password ) :
    		username(username),
    		password(password) {} //Was genau passiert hier? Ist das eine eigene Funktion? Einmal erklären bitte :D
    };
    
    int main()
    {
    	std::vector<data> users;//Ich benutze immer den Array sollte ich den Vector benutzen? Und woher weiß ich welches "Element" ich nehmen soll?
    	users.emplace_back( "Horst", "B4um" );//Und hier einmal die "Funktion"? oder was soll das darstellen? 
    
    	std::cout << users.front().username << "-------" << users.front().password;//Was bedeutet "front()"?
    }
    

    Danke! Meine Fragen stehen im Code. 🙂

    Bashar schrieb:

    Abgesehen davon, dass du hier keine Referenz auf einen Zeiger brauchst, schreibt man das data *& user. Was du geschrieben hast heißt "Zeiger auf Referenz", und sowas gibt es nicht.

    Stimmt habe ich vergessen. Ein Zeiger schreibt ja direkt in die Speicherzelle.


  • Mod

    data( std::string const& username, std::string const& password ) :
            username(username),
            password(password) {} //Was genau passiert hier? Ist das eine eigene Funktion? Einmal erklären bitte :D
    

    Das ist ein Konstruktor.

    Ein Konstruktor initialisiert die Basisklassen und Member eines Objektes und kann im Rumpf wie eine ganz normale Funktion noch andere Dinge erledigen. In diesem Fall initialisiert er die Member username und password mit den dazugehörigen Funktionsparametern (die den gleichen Namen tragen dürfen).

    Und der Konstruktor ist in der Tat eine eigene Funktion, man nennt ihn eine spezielle Memberfunktion (engl. special member function).

    //Ich benutze immer den Array sollte ich den Vector benutzen?

    Ja. Wenn die Anzahl der Elemente im Voraus feststeht geht auch ein Array, aber dann müssen die Elemente in den meisten Fällen default-Konstruierbar sein - bei vector gilt das nicht. Die Größe eines vector s kannst du im Nachhinein ändern - und alle Elemente einzeln einfügen.

    //Und hier einmal die "Funktion"?

    Diese Funktion fügt ein Element in den Container ein. Sie ist auch bei anderen sequentiellen Containern wie list oder deque vorhanden.

    Im Gegensatz zu push_back , welches ein Objekt nimmt und eine Kopie* davon einfügt, nimmt emplace_back direkt die Konstruktorargumente entgegen.

    //Was bedeutet "front()"?

    Ist genau dasselbe wie vec[0] . Man kann es aber in generischem Code nutzen um vom Containertyp unabhängiger zu werden (und es ist hübscher und aussagekräftiger als *begin() ).

    Bei vector kann man wie gewohnt mit dem Indexoperator arbeiten. Zusätzlich gibt es noch die Memberfunktion at , welches einen Range-Check durchführt (und eine Exception schmeißt falls der Index ungültig ist).

    * ~In C++11 kann auch gemoved werden.~



  • Danke für die Antwort!
    Kann man das aber auch in einer Funktion lösen (auch wenn es ein wenig schwerer ist). Weil ich finde das direkt im struct-Element(also so) ein wenig schwer zu verstehen.

    data( std::string const& username,
              std::string const& password ) :
            username(username),
            password(password) {}
    

    Du hast es mir jedzt schon erklärt aber wirklich verstehen tue ich es nocht nicht.

    Im Gegensatz zu push_back, welches ein Objekt nimmt und eine Kopie* davon einfügt, nimmt emplace_back direkt die Konstruktorargumente entgegen.

    Hier genauso. Es wird der Vector um eins vergrößert richtig? Und mit jeder vergrößerung kann ich 2 Variablen neu ansprechen? (1x username & 1x password?)

    Gruß



  • Fensterscheibe schrieb:

    Danke für die Antwort!
    Kann man das aber auch in einer Funktion lösen (auch wenn es ein wenig schwerer ist). Weil ich finde das direkt im struct-Element(also so) ein wenig schwer zu verstehen.

    data( std::string const& username,
              std::string const& password ) :
            username(username),
            password(password) {}
    

    Du hast es mir jedzt schon erklärt aber wirklich verstehen tue ich es nocht nicht.

    Hattest du schon Memberfunktionen?
    Wenn nein, dann ist das schwer zu verstehen.
    Stell dir die Funktion so vor:

    struct data {...}
    data make_data(std::string const& username, std::string const& password)
    {
      data result;
      result.username = username;
      result.password = password;
      return result;
    }
    
    int main()
    {
      data d = make_data("foo", "bar");
    }
    

    Nur anstatt das so zu schreiben steht das da eben in der struct drin.



  • Hattest du schon Memberfunktionen?
    Wenn nein, dann ist das schwer zu verstehen.

    Ja ich habe das Kapitel durchgelesen und damit noch nie etwas richtiges angestellt. (leider)

    Auf jedenfall ist das um einiges einfacher zu verstehen 😃 (finde ich)

    Aber wie ich sehe ich das, die oder der struct nun global, sprich für jeden zugänglich. Das sollte man doch möglichst verhindern oder nicht?
    Und warum ist der Rückgabetyp der Funktion data? Damit das in das, die oder der struct geschrieben wird?

    Und mein letzte Frage
    Was hat es mit diesen foo & bar auf sich? Ich lese das so oft hier kann das aber nicht zuordnen 😃 Oder wurde das einfach weitergetragen und hat eigendlich gar keinen Sin?

    Gruß



  • Fensterscheibe schrieb:

    Aber wie ich sehe ich das, die oder der struct nun global, sprich für jeden zugänglich. Das sollte man doch möglichst verhindern oder nicht?

    Ja, das Prinzip dahinter heißt Kapselung und macht man durch private Daten.

    Und warum ist der Rückgabetyp der Funktion data? Damit das in das, die oder der struct geschrieben wird?

    Das ist nur ein Beispiel, das ist nicht wirklich so wenn du einen Konstruktor schreibst.

    Und mein letzte Frage
    Was hat es mit diesen foo & bar auf sich? Ich lese das so oft hier kann das aber nicht zuordnen 😃 Oder wurde das einfach weitergetragen und hat eigendlich gar keinen Sin?

    Nein, das macht keinen Sinn: http://de.wikipedia.org/wiki/Metasyntaktische_Variable





  • Okay also ich muss nochmal fragen ^^
    So schnell werdet ihr mich nicht los haha 😃

    So ich habe versucht nun euer Hilfe zusammen zu fügen aber ohne Erfolg...

    struct data {
        string username;
        string password;
    };
    
    void make_data(std::string const& username, std::string const& password){
    
      user.username = username;
      user.password = password;
    
    }
    
    int main(){
        std::vector<data> users;//Das habe ich einfach kopiert...
    
        string username="foo";
        string password="bar";
    
        data user;
        make_data(username, password);
    
        return 0;
    }
    

    Ich weiß das der Vector gar nicht hochgezählt wird, und gar nicht so wirklich eine Verbindung herrscht. Ich bekomme es aber auch nicht besser hin :s

    Und mein Wunsch war halt einen "User" mit Passwort und Benutzernamen anlegen zu können.


  • Mod

    void make_data(std::string const& username, std::string const& password){
     
      user.username = username;
      user.password = password;
     
    }
    

    Vergleich doch mal mit der Funktion, die dir gezeigt wurde. Alles was wichtig war, hast du entfernt, bis das Ergebnis überhaupt keinen Sinn mehr machte.



  • Ich weiß ich habe sehr vieles rausgenommen.
    Z.B. das hier data user; ich dachte das müsste ich in der main machen weil ich möchte die ganzen User auch noch ausgeben und wenn ich data user; in der Funktion schreibe ist dies nicht gültig in der main.
    Dann return result;

    Und warum ist der Rückgabetyp der Funktion data? Damit das in das, die oder der struct geschrieben wird?

    Das ist nur ein Beispiel, das ist nicht wirklich so wenn du einen Konstruktor schreibst.

    Deswegen frage ich ja... Ich komme damit so gar nicht klar momentan 😕



  • Wenn du bisher noch gar keine Memberfunktionen verwendest (bzw. verstanden hast), dann nimm ersteinmal diese Version:

    struct data
    {
        string username;
        string password;
    };
    
    void make_data(data& user, std::string const& username, std::string const& password)
    {
        user.username = username;
        user.password = password;
    }
    
    int main()
    {
        std::vector<data> users;
    
        string username="foo";
        string password="bar";
    
        data user;
        make_data(user, username, password);
    
        users.push_back(user);
    
        std::cout << users.front().username << "-------" << users.front().password << '\n';
    
        return 0;
    }
    

    Ich hoffe, ich habe jetzt keinen Syntax-Error hier eingebaut.
    Und versuche jetzt, diesen Code zu verstehen...



  • Oha ja! Das ist mir um einiges Verständlicher.
    Aber mein Versuch ähnelt dem ja schon ein wenig... 😃

    Nur wenn ich jedzt z.B. das in einer Schleife packe sodass ich 5 User angelegt habe, wie spreche ich die nun einzelnd an?
    Das wäre dann auch schon meine letzte Frage 🙂



  • Du kannst über den vector iterieren:

    for(std::vector<data>::const_iterator it = users.begin(); it != users.end(); ++it)
      cout << it->username;
    

    In C++11 geht das auch kürzer mit

    for(const auto & user : users)
      cout << user.username;
    

    s.a. Ten C++11 Features Every C++ Developer Should Use



  • Danke für die Antwort. Und ich hätte mir vorher nochmal angucken sollen wie son Vektor überhaupt "funktioniert".
    Aufjedenfall möchte ich jedzt die eingaben die in dem Vektor gespeichert sind in eine .txt schreiben, innerhalb einer Funktion. Das Problem dabei ist das der Vektor halt nur in der main bekannt ist.

    struct data{
        string username;
        string password;
    };
    
    void write(data user, ??){ //Hier
        fstream p_shadow;
        p_shadow.open("shadow.txt", ios::out|ios::trunc);
        if(!p_shadow){
            cout << "Datei konnt nicht geöffnet werden!";
        }
        else{
            for(unsigned int i=0;i<users.size();i++){
                cout << users[i].username << '\n';
                cout << users[i].password << '\n';
            }
            p_shadow.close();
        }
    }
    
    int main(){
        vector<data> users;
    
        write(user, ??) //Hier
    }
    

    Und ich weiß nicht wie ich den Vektor nun übergebe.



  • Du übergibst ihn genauso wie du alles andere auch an Funktionen übergibst...?


Log in to reply