结构初始化向量


76

我想知道如何使用该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");


嘿,我添加了一个新答案,请看一下
Onk_r

Answers:


94

创建矢量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;
}

您无法使用[#]访问向量,直到该索引中的向量中存在一个元素。本示例填充[#],然后对其进行修改。


2
subject.resize(2);可能是一个更快,更清晰的解决方案...甚至vector<subject> sub(2);
Kerrek SB 2011年

1
是的,我同意。:)我认为他并不太了解效率的过度分配以及矢量的大小增长-这看起来更像是c ++问题的介绍。
约翰·汉弗莱斯

1
@ w00te我添加了几个您可能忘记添加的引号。希望没事。
Natan Streppel 2013年

2
@nims都很好!:)令我惊讶的是,这个错误在35,000个问题上徘徊了3年,哈哈。
约翰·汉弗莱斯


13

您还可以在此类情况下使用大括号初始化列表中的聚合初始化。

#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


10

您不能通过下标访问空向量的元素。
在上使用[]运算符时,请始终检查向量是否为空以及索引是否有效std::vector
[]如果不存在则不添加元素,但是如果索引无效,则会导致未定义行为

您应该创建结构的临时对象,将其填充,然后使用将其添加到向量中 vector::push_back()

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

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

然后,我认为初始化该结构的向量的方法很不错,不是吗?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.