89

push_backメソッドを使用して構造体のベクトルに値を追加する方法を知りたい

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


vector<subject> sub;

では、どうすれば要素を追加できますか?

文字列名(サブジェクト名)を初期化する関数があります

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

}

関数呼び出し

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

5 に答える 5

110

ベクトル、push_back要素を作成し、次のように変更します。

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

そのインデックスのベクトルに要素が存在するまで、[#]を使用してベクトルにアクセスすることはできません。この例では、[#]にデータを入力し、後で変更します。

于 2011-11-09T15:39:15.327 に答える
61

新しい現在の標準を使用する場合は、次のように実行できます。

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

また

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

これらは、のデフォルトの構成を必要としませんsubject

于 2011-11-09T18:53:42.707 に答える
18

このような状況では、ブレース付き初期化リストの集計初期化を使用することもできます。

#include <vector>
using namespace std;

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

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

ただし、構造体のメンバーはそれほど単純ではない場合があるため、コンパイラーにその型を推測する手を与える必要があります。

したがって、上記を拡張します。

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

ブレース付き初期化子がないassessmentと、型を推測しようとしたときにコンパイラーは失敗します。

上記は、c++17のgccでコンパイルおよびテストされています。ただし、c++11以降で機能するはずです。c ++ 20では、指定子の構文が表示される場合があります。これにより、次のことが可能になることを願っています。

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

ソース:http ://en.cppreference.com/w/cpp/language/aggregate_initialization

于 2018-04-29T10:00:36.150 に答える
13

空のベクトルの要素に添え字でアクセスすることはできません。で演算子
を使用している間は、ベクトルが空ではなく、インデックスが有効であることを常に確認してください。要素が存在しない場合は要素を追加しませんが、インデックスが無効な場合は未定義動作が発生します。[]std::vector
[]

構造の一時オブジェクトを作成し、それを埋めてから、を使用してベクターに追加する必要があります。vector::push_back()

subject subObj;
subObj.name = s1;
sub.push_back(subObj);
于 2011-11-09T15:34:48.147 に答える
3

受け入れられた答えを見た後、必要なベクトルのサイズがわかっている場合は、ループを使用してすべての要素を初期化する必要があることに気付きました

しかし、私は次のようにdefault_structure_elementを使用してこれを行うのが新しいことを発見しました...

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

それなら、構造体のベクトルを初期化するのは良い方法だと思いますね。

于 2018-07-14T06:22:25.117 に答える