86 votes

Vecteur d'initialisation des structs

Je veux savoir comment je peux ajouter des valeurs à mon vecteur de structs en utilisant la fonction push_back méthode

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

vector<subject> sub;

Alors maintenant, comment puis-je y ajouter des éléments ?

J'ai une fonction qui initialise le nom de la chaîne de caractères (nom du sujet).

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);

}

Appel de fonction

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

1 votes

D'autres moyens d'initialisation du vecteur : stackoverflow.com/questions/4155845/vecteur-de-structures

0 votes

Hey j'ai ajouté une nouvelle réponse s'il vous plaît regarder sur cela

106voto

w00te Points 11664

Créer le vecteur, l'élément push_back, puis le modifier comme suit :

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;
}

Vous ne pouvez pas accéder à un vecteur avec [#] tant qu'un élément n'existe pas dans le vecteur à cet indice. Cet exemple remplit le [#] et le modifie par la suite.

2 votes

subject.resize(2); peut être une solution un peu plus rapide et plus claire... ou même vector<subject> sub(2); .

1 votes

Oui, je suis d'accord. :) Je ne pensais pas qu'il comprendrait tout à fait la surallocation pour l'efficacité et comment un vecteur croît en taille - cela ressemble plus à un problème d'introduction au C++.

1 votes

@w00te J'ai ajouté quelques guillemets que vous avez probablement oublié d'ajouter. J'espère que cela ne pose pas de problème.

61voto

phresnel Points 20082

Si vous souhaitez utiliser la nouvelle norme actuelle, vous pouvez le faire :

sub.emplace_back ("Math", 70, 0); // requires a fitting constructor, though

ou

sub.push_back ({"Math", 70, 0}); // works without constructor

.

2 votes

La première partie de votre réponse n'est pas exacte ; vous ne pouvez pas replacer un struct sans un ctor correspondant. rextester.com/VQWCT51042

20voto

Vous pouvez également utiliser l'initialisation agrégée à partir d'une liste d'initialisation entre accolades dans des situations comme celles-ci.

#include <vector>
using namespace std;

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

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

Parfois, cependant, les membres d'une structure ne sont pas aussi simples, et vous devez donc donner un coup de main au compilateur pour déduire ses types.

En prolongement de ce qui précède.

#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}
                         }}
    };
}

Sans le assessment dans l'initialisateur entre parenthèses, le compilateur échouera lorsqu'il tentera de déduire le type.

Ce qui précède a été compilé et testé avec gcc en c++17, mais devrait fonctionner à partir de c++11. En c++20, nous verrons peut-être la syntaxe des désignateurs, mon espoir est qu'elle permette ce qui suit

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

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

13voto

Alok Save Points 115848

Vous ne pouvez pas accéder aux éléments d'un vecteur vide par un indice.
Vérifiez toujours que le vecteur n'est pas vide et que l'index est valide lorsque vous utilisez la fonction [] opérateur sur std::vector .
[] n'ajoute pas d'éléments s'il n'y en a pas, mais il provoque l'apparition d'un Comportement indéfini si l'index est invalide.

Vous devez créer un objet temporaire de votre structure, le remplir, puis l'ajouter au vecteur, en utilisant la commande vector::push_back()

subject subObj;
subObj.name = s1;
sub.push_back(subObj);

3voto

Onk_r Points 728

Après avoir regardé la réponse acceptée, j'ai réalisé que si nous connaissons la taille du vecteur requis, nous devons utiliser une boucle pour initialiser chaque élément.

Mais j'ai trouvé un nouveau moyen de le faire en utilisant default_structure_element comme suit...

#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;
  } 
}

Alors je pense que c'est une bonne façon d'initialiser un vecteur de la structure, n'est-ce pas ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X