使用初始化列表填充C++中的多维结构数组时出现问题

Problems populating a multi-dimensional array of structs in C++ with an initialisation list

本文关键字:数组 结构 问题 初始化 列表 填充 C++      更新时间:2023-10-16

我正在创建一个文本冒险,其中包含房间名称,描述以及提示和物品的空间。

这是到目前为止解决方案的一部分,一个具有四个字符串条目的简单结构。一个要求是保持房间初始化数据的可读性和可编辑性,因为 4x4 数组可以作为我的游戏世界的网格。

using namespace std;
#include <string>
struct Room
{
string name;
string description;
string itemHint;
string item;
};
Room rooms[4][4]= {
{{"...", "...", "...", "..."},
{"...", "...", "...", "..."},
{"...", "...", "...", "..."},
{"...", "...", "...", "..."}}, // rooms[0..3][0] data
{{"...", "...", "...", "..."}, // and so on

现在这在某种程度上是有效的。但是,在打印游戏世界的房间地图时,我收到重复的条目。代码每行复制房间数据四次 [0..0][0..3]。

void PrintMap()
{
cout << endl;
for (int v = 0; v < 4; v += 1)
{
for (int h = 0; h < 4; h += 1)
{
if (currentRoom.h == h && currentRoom.v == v)
cout << "@";
else
cout << " ";
cout << rooms[h, v]->name;
string charstring = rooms[h, v]->name;
int chars = charstring.length();
int endSpaces = 24 - 1 - chars;
for (int charSpaces = 1; charSpaces < endSpaces + 1; charSpaces += 1)
cout << " ";
}
cout << endl << endl << endl;
}
}

下面是控制台应用程序打印的房间地图的屏幕截图,以帮助更好地解释这一点:

房间地图

我几乎明白为什么会发生这种情况,但也许有人可以解释它并有一个有效的解决方案。当然,正如我所说,我希望保持房间数据的代码格式可读,我很乐意接受任何代码设计添加。

由于矩阵上的混淆,您可能初始化数据不正确。您需要将其视为一个表,其中第一个维度是行,第二个维度是房间的列。

由于您正在初始化结构,因此 c++ 能够使用以下语法进行初始化

Room room = {"A Room name", "A room description", "A hint", "An item"};

如此处所述

初始化

结构时,列表中的第一个初始值设定项初始化第一个声明的成员(除非指定了指示符((自 C99 以来(,所有没有指示符的后续初始值设定项(自 C99 以来(初始化在由前一个表达式初始化的结构成员之后声明的结构成员。

现在,考虑到这种类型的初始化,请考虑以下事项

Room rooms[4][4] = {
{
{"...", "...", "...", "..."}, // room col 0 at row 0 [0][0]
{"...", "...", "...", "..."}, // room col 1 at row 0 [0][1]
{"...", "...", "...", "..."}, // room col 2 at row 0 [0][2]
{"...", "...", "...", "..."}  // room col 3 at row 0 [0][3]
},
{
{"...", "...", "...", "..."}, // room col 0 at row 1 [1][0]
{"...", "...", "...", "..."}, // room col 1 at row 1 [1][1]
{"...", "...", "...", "..."}, // room col 2 at row 1 [1][2]
{"...", "...", "...", "..."}, // room col 3 at row 1 [1][3]
}
};

按预期检查房间应该可以正常工作

// Print all data in the matrix.
for (int rowIndex = 0; rowIndex < 4; rowIndex++) {
cout << "--- Room info at row " << rowIndex << endl;
for (int colIndex = 0; colIndex < 4; colIndex++) {
cout << "Room name at point " << rowIndex << "," << colIndex << ":" << rooms[rowIndex][colIndex].name << endl;
}
}

我建议在提供的有关结构的链接上阅读更多内容。希望这能解决您的困惑。

编辑:

看到您的PrintMap方法后,我注意到您在要实现的上下文中错误地使用了 Arrow 运算符->

您尝试访问矩阵中特定行/列的方式不是这样做的本机方式。在这种情况下,rooms[h, v]->name等效于rooms[v]->name.您在此处执行的是取消引用左侧的指针,并在第x行的运算符的右侧访问结构的指定成员的值。

下面生成相同的输出,其中v是矩阵中的行。

string val = (*rooms[v]).name;
val = rooms[v]->name

数组只是指向第一个元素地址的指针,然后编译器根据指定数组的宽度保留一定数量的连续地址。因此,从理论上讲,您的代码可以很好地执行,但会给您带来不希望的结果。

考虑到这一点,这就是为什么您基本上也看到重复项的原因,因为您的印象是数组get运算符分别获取每次迭代的行和列,但它只是分别获取行v的值在您的情况下。

最好的选择是在迭代矩阵时使用点.运算符,以减少混淆并为您提供所需的输出。

阅读更多关于箭头与点运算符的信息也可能有所帮助。我希望这些信息对您有用。这里有一个关于两者的有用讨论。