简体   繁体   English

在数组中一次分配整个结构

[英]Assign a whole struct at once in an array

I am learning C++ and I have a problem with struct and arrays. 我正在学习C ++,但struct和数组有问题。 My struct is: 我的结构是:

struct board
{
    string name;
    string desc;
    int nval;
    int sval;
    int eval;
    int wval;
};

My array looks like this: 我的数组如下所示:

board field[10][10];

I'm able to do for example: 我可以做例如:

field[5][6].name = "ExampleName";
field[5][6].desc = "This is an example";
field[5][6].nval = 3;
//and so on...

But I want to assign to the whole structure at once, something like this: 但我想立即分配给整个结构,如下所示:

field[5][6] = {"ExampleName", "This is an example", 3, 4, 5, 6};
//so I don't have to type everything over and over again...

What you are trying to do is allowed in C standard. C标准允许您尝试执行的操作。 It seems to be working in C++ as well. 它似乎也可以在C ++中工作。 I verified it in C++11: 我在C ++ 11中验证了它:

struct board
{
string name;
string desc;
int nval;
int sval;
int eval;
int wval;
}field[10][10];

int main()
{    
field[5][6]={"ExampleName","This is an example",3,4,5,6};
cout<<field[5][6].name<<endl;
cout<<field[5][6].sval<<endl;
return 0;
}

It's printing correctly. 打印正确。 So you should be able to do that. 因此,您应该能够做到这一点。

I'm afraid you can't do it this way. 恐怕你不能这样。

But in real life it's not a problem because you don't normally need to fill this kind of fields manually. 但是在现实生活中,这不是问题,因为您通常不需要手动填写此类字段。 You usually do it in a loop. 您通常会循环执行。

In case you wouldn't mind runtime initialization, I'd do it this way: 如果您不介意运行时初始化,我可以这样做:

    // in the beginning make these arrays
string names[10*10] = {
    "example 1 name"
    "example 2 name"
    "blah blah blah "
};

string descriptions[100] = {

};
//and then just loop through that

int i,j;
for (int k = 0; k != 10*10; ++k) { // 10*10 size of a board
        if (j == 10) {
            j = 0;
            i++
        }

        field[i][j].name = names[k]// get it from names
        field[i][j].desc = // get somehow the description,...
        ++j
    }

}

As has been mentioned, C99 as well as C# support a form of that syntax, but standard C++ doesn't. 如前所述,C99和C#支持该语法的一种形式,但标准C ++不支持。 You could do it with by adding a constructor to your struct. 可以通过向您的结构添加构造函数来实现。 Be aware that this will not be ANSI C compatible anymore. 请注意,这将不再与ANSI C兼容。

struct board
{
    string name;
    string desc;
    int nval;
    int sval;
    int eval;
    int wval;

    board()
    {
    }

    board(string name, string desc, int nval, int sval, int eval, int wval)
    {
        this->name = name;
        this->desc = desc;
        this->nval = nval;
        this->sval = sval;
        this->eval = eval;
        this->wval = wval;
    }
};

field[1][2] = board("name", "desc", 1, 2, 3, 4);

If you define constructor that takes parameters you will be able to create temporary and initialize given element with it. 如果定义带有参数的构造函数,则可以创建临时变量并使用它初始化给定的元素。 You'll need to define and default constructor as well: 您还需要定义和默认构造函数:

struct board
{
   string name;
   string desc;
   int nval;
   int sval;
   int eval;
   int wval;

   board():
     name(""),
     desc(""),
     nval(0),
     sval(0),
     eval(0),
     wval(0){}

   board(
     const string& name,
     const string& desc,
     int nval,
     int sval,
     int eval,
     int wval):
   name(name),
   desc(desc),
   nval(nval),
   sval(sval),
   eval(eval),
   wval(wval){}
};

int main()
{
   board field[10][10];
   field[5][6]= board("ExampleName","This is an example",3,4,5,6);
   return 0;
}

If you really need to define hand-picked values for all of your 100 fields, you could make it easier by writing all the arguments in a text file and then parse the file and fill your array with the extracted values. 如果确实需要为所有100个字段定义手动选择的值,则可以通过在文本文件中写入所有自变量,然后解析该文件并用提取的值填充数组来简化操作。 The file might look like 该文件可能看起来像

0 0
Corner field
Here it begins
0 1 2 3

0 1
ExampleName
This is an example
3 4 5 6

and so on. 等等。 Then when reading the file you can use istream::getline to extract text strings, and istream::operator>> to extract numbers. 然后,在读取文件时,可以使用istream::getline提取文本字符串,并使用istream::operator>>提取数字。

But it's still a lot of pain. 但这仍然很痛苦。 Are you sure that there is no automatic way to generate at least most of your values? 您确定没有自动方法来生成至少大多数值吗?

The question is not too clear as of what you mean with one line , so I will start providing suggestions: 关于一行的含义,这个问题不太清楚,因此我将开始提供建议:

Use aggregate initialization: 使用聚合初始化:

board fields[10][10] = { 
                  { {"ExampleName","This is an example",3,4,5,6}, // Element 0,0
                    {"ExampleName","This is an example",3,4,5,6}, // Element 0,1
                // ...
                  },
                  { {"ExampleName","This is an example",3,4,5,6}, // Element 1,0
                // ... 
                  }
                };

This is the closest to one-liner that you can get, it is valid C++ (in all variants, given that board is an aggregate, an thus board[10][10] is also an aggregate), but it can be hard to read. 这是您可以获得的最接近的单行代码,它是有效的C ++(在所有变体中,鉴于board是一个集合,因此board[10][10]也是一个集合),但是很难做到读。

The next step is getting closer to what you are doing, which is initializing each element (rather than the array), for that in C++11 you can use the same type of initialization as you suggest. 下一步将接近您正在执行的操作,即初始化每个元素(而不是数组),为此,在C ++ 11中,您可以使用建议的相同类型的初始化。 In C++03 you need to do this through either a constructor (note, this will change the properties of the type, and you will need to create a default constructor for the array): 在C ++ 03中,您需要通过一个构造函数来执行此操作(请注意,这将更改类型的属性,并且需要为数组创建一个默认构造函数):

 struct board {
    string name;
    string desc;
    int nval;
    int sval;
    int eval;
    int wval;
    board() {}  // [*]
    board( const char* name, const char* desc, int n, int s, int e, int w )
       : name(name), desc(desc), nval(n), sval(s), eval(e), wval(w)
    {}
 };
 board fields[10][10];  // [*] this requires the default constructor [*]

 fields[5][6] = board("ExampleName","This is an example",3,4,5,6);

Or through a function: 或通过一个函数:

board create_board( const char* name, const char* desc, ... ) {
   board res = { name, desc, ... };
   return res;
}

Note that in both these cases the elements in the array are initialized during the array initialization, and then a new object is copied on top of them. 请注意,在这两种情况下,在数组初始化期间都会初始化数组中的元素,然后在它们之上复制一个新对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM