Vektor der Strukturinitialisierung

75

Ich möchte wissen, wie ich mit der push_backMethode meinem Strukturvektor Werte hinzufügen kann

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


vector<subject> sub;

Wie kann ich nun Elemente hinzufügen?

Ich habe eine Funktion, die den String-Namen initialisiert (Betreff-Name dazu)

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");
SRN
quelle
1
andere Mittel zur Vektorinitialisierung: stackoverflow.com/questions/4155845/vector-of-structures
jpalecek
Hey, ich habe eine neue Antwort hinzugefügt, bitte schauen Sie sich das an
Onk_r

Antworten:

94

Erstellen Sie den Vektor push_back element und ändern Sie ihn 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.

John Humphreys - w00te
quelle
2
subject.resize(2);kann eine etwas schnellere und klarere Lösung sein ... oder sogar vector<subject> sub(2);.
Kerrek SB
1
Ja ich stimme zu. :) Ich dachte nicht, dass er die Gesamtzuordnung für Effizienz und das Wachstum eines Vektors verstehen würde - dies sieht eher aus wie eine Einführung in das C ++ - Problem.
John Humphreys - w00te
1
@ w00te Ich habe ein paar Anführungszeichen hinzugefügt, die Sie wahrscheinlich vergessen haben, hinzuzufügen. Hoffe das ist ok
Natan Streppel
2
@nims Alles gut! :) Ich bin überrascht, dass der Fehler 3 Jahre lang bei einer Frage mit 25.000 Ansichten aufgetreten ist, haha.
John Humphreys - w00te
54

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.

Sebastian Mach
quelle
2
Der erste Teil Ihrer Antwort ist nicht korrekt. Sie können eine Struktur nicht ohne einen passenden ctor rextester.com/VQWCT51042
Jean-Simon Brochu
12

Sie können auch festlegen, 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 nicht so einfach, sodass Sie dem Compiler bei der Ableitung seiner Typen helfen 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 den assessmentim geschweiften Initialisierer fehlgeschlagenen Compiler schlägt der Compiler fehl, wenn versucht wird, 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

Rikard Söderström
quelle
9

Sie können nicht per Index auf Elemente eines leeren Vektors zugreifen.
Stellen Sie immer sicher, dass der Vektor nicht leer und der Index gültig ist, während Sie den []Operator aktivieren std::vector.
[]fügt keine Elemente hinzu, wenn keine vorhanden sind, verursacht jedoch ein undefiniertes Verhalten, wenn der Index ungültig ist.

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

subject subObj;
subObj.name = s1;
sub.push_back(subObj);
Alok Speichern
quelle
3

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 zu tun, wie folgt ...

#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?

Onk_r
quelle