web-dev-qa-db-de.com

Vektor der Strukturinitialisierung

Ich möchte wissen, wie ich meinem Strukturvektor Werte hinzufügen kann, indem ich Push_back Methode

struct subject
{
  string name;
  int marks;
  int credits;
};


vector<subject> sub;

Wie kann ich nun Elemente hinzufügen?

Ich habe eine Funktion, die den Namen der Zeichenfolge initialisiert (den Namen des Betreffs)

void setName(string s1, string s2, ...... string s6)
{
   // how can i set name too sub[0].name= "english", sub[1].name = "math" etc

  sub[0].name = s1 // gives segmentation fault; so how do I use Push_back method?

  sub.name.Push_back(s1);
  sub.name.Push_back(s2);
  sub.name.Push_back(s3);
  sub.name.Push_back(s4);

  sub.name.Push_back(s6);

}

Funktionsaufruf

setName("english", "math", "physics" ... "economics");
64
SRN

Erstellen Sie einen Vektor, ein Push_back-Element, und ändern Sie ihn dann wie folgt:

struct subject {
    string name;
    int marks;
    int credits;
};


int main() {
    vector<subject> sub;

    //Push back new subject created with default constructor.
    sub.Push_back(subject());

    //Vector now has 1 element @ index 0, so modify it.
    sub[0].name = "english";

    //Add a new element if you want another:
    sub.Push_back(subject());

    //Modify its name and marks.
    sub[1].name = "math";
    sub[1].marks = 90;
}

Sie können mit [#] nicht auf einen Vektor zugreifen, bis an diesem Index ein Element im Vektor vorhanden ist. In diesem Beispiel wird das [#] ausgefüllt und anschließend geändert.

Wenn Sie den neuen aktuellen Standard verwenden möchten, können Sie dies tun:

sub.emplace_back ("Math", 70, 0);

oder

sub.Push_back ({"Math", 70, 0});

Diese erfordern keine Standardkonstruktion von subject.

44
Sebastian Mach

Sie können nicht mit dem Index auf Elemente eines leeren Vektors zugreifen.
Überprüfen Sie immer, dass der Vektor nicht leer ist und der Index gültig ist, wenn Sie den Operator [] Für std::vector Verwenden.
[] Fügt keine Elemente hinzu, wenn keine vorhanden sind, verursacht jedoch ein ndefiniertes Verhalten, wenn der Index ungültig ist.

Sie sollten ein temporäres Objekt Ihrer Struktur erstellen, es auffüllen und dann mit vector::Push_back() zum Vektor hinzufügen.

subject subObj;
subObj.name = s1;
sub.Push_back(subObj);
8
Alok Save

Sie können auch angeben, welche Aggregatinitialisierung aus einer geschweiften Initialisierungsliste für Situationen wie diese verwendet werden soll.

#include <vector>
using namespace std;

struct subject {
    string name;
    int    marks;
    int    credits;
};

int main() {
    vector<subject> sub {
      {"english", 10, 0},
      {"math"   , 20, 5}
    };
}

Manchmal sind die Mitglieder einer Struktur jedoch möglicherweise nicht so einfach, sodass Sie dem Compiler bei der Ableitung seiner Typen behilflich sein müssen.

Also weiter oben.

#include <vector>
using namespace std;

struct assessment {
    int   points;
    int   total;
    float percentage;
};

struct subject {
    string name;
    int    marks;
    int    credits;
    vector<assessment> assessments;
};

int main() {
    vector<subject> sub {
      {"english", 10, 0, {
                             assessment{1,3,0.33f},
                             assessment{2,3,0.66f},
                             assessment{3,3,1.00f}
                         }},
      {"math"   , 20, 5, {
                             assessment{2,4,0.50f}
                         }}
    };
}

Ohne das assessment im geschweiften Initialisierer schlägt der Compiler fehl, wenn er versucht, den Typ abzuleiten.

Das obige wurde mit gcc in c ++ 17 kompiliert und getestet. Es sollte jedoch ab c ++ 11 funktionieren. In c ++ 20 sehen wir möglicherweise die Bezeichnersyntax. Ich hoffe, dass dies Folgendes zulässt

  {"english", 10, 0, .assessments{
                         {1,3,0.33f},
                         {2,3,0.66f},
                         {3,3,1.00f}
                     }},

quelle: http://en.cppreference.com/w/cpp/language/aggregate_initialization

6

Nachdem ich mir die akzeptierte Antwort angesehen hatte, wurde mir klar, dass wir, wenn wir die Größe des erforderlichen Vektors kennen, eine Schleife verwenden müssen, um jedes Element zu initialisieren

Aber ich fand neu, um dies mit default_structure_element wie folgt zu tun ...

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

typedef struct subject {
  string name;
  int marks;
  int credits;
}subject;

int main(){
  subject default_subject;
  default_subject.name="NONE";
  default_subject.marks = 0;
  default_subject.credits = 0;

  vector <subject> sub(10,default_subject);         // default_subject to initialize

  //to check is it initialised
  for(ll i=0;i<sub.size();i++) {
    cout << sub[i].name << " " << sub[i].marks << " " << sub[i].credits << endl;
  } 
}

Dann denke ich, dass es gut ist, einen Vektor der Struktur zu initialisieren, nicht wahr?

2
Onk_r