【问题标题】:Problems populating a multi-dimensional array of structs in C++ with an initialisation list在 C++ 中使用初始化列表填充多维结构数组的问题
【发布时间】:2020-05-21 17:01:41
【问题描述】:

我正在创建一个包含房间名称、描述以及提示和项目空间的文本冒险。

这是目前解决方案的一部分,一个包含四个字符串条目的简单结构。一个要求是保持房间初始化数据的可读性和可编辑性,因为 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;
    }
}

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

room map

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

【问题讨论】:

  • 绘制房间的代码在哪里?

标签: c++ string multidimensional-array struct


【解决方案1】:

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

由于您正在初始化一个 struct c++ 能够使用以下语法进行某种类型的初始化

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

据记录 here

当初始化一个结构体时,列表中的第一个初始化器会初始化第一个声明的成员(除非指定了指示符)(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 方法后,我注意到您在要实现的目标的上下文中错误地使用了箭头运算符 -&gt;

您尝试访问矩阵中特定行/列的方式不是这样做的本机方式。在这种情况下,rooms[h, v]-&gt;name 等价于 rooms[v]-&gt;name。您在这里所做的是取消引用左侧的指针并访问位于行首x 的运算符右侧的结构的指定成员的值。

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

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

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

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

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

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

【讨论】:

  • 感谢您的完整描述。我已经遵守数据列表中结构的初始化规则,我已经三重检查了这一点 - 尽管我的第一个示例中的代码不完整。也许我的问题在于void PrintMap() 使用rooms[rowIndex][colIndex]-&gt;name 而不是rooms[rowIndex][colIndex].name,因为我无法访问房间数据。带有更正的编译器警告:Error C2228 left of 'name' must have class/struct/union
  • @SquareMezzmer 我更新了我的帖子。让我知道这是否能解决一些问题。
  • 感谢您的详尽回答。这澄清了正在发生的事情并解释了问题。但是我仍然不确定为什么我无法使用点运算符访问我的房间数据。有没有办法可以引用数组?正如我所说,在代码中,无论我在哪里引用它,编译器都会出错expression must have class type
  • @SquareMezzmer 您可以在嵌套循环中按照(rooms[v] + h)-&gt;name 的行做一些事情,其中​​h 是距每行开头的列偏移量。这相当于rooms[v][h].name。希望所有这些都对您有所帮助。
  • 谢谢,会继续努力的!
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 2018-01-31
  • 2013-02-28
  • 2014-06-19
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多