从文件加载数组

Loading array from file

本文关键字:数组 加载 文件      更新时间:2023-10-16

我正在尝试加载一个整数文件,将它们添加到 2D 数组中,遍历数组,并根据当前索引处的整数(Tile ID)将瓷砖添加到我的关卡。我的问题似乎是数组以错误的顺序加载/迭代。这是我从中加载的文件:

测试.txt

02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01

这是关卡构造函数:

Level::Level(std::string levelpath, int _width, int _height)
{
    std::ifstream levelfile(levelpath);
    width = _width;
    height = _height;
    int ids[15][9];
    while (levelfile.is_open()) {
        std::copy_n(std::istream_iterator<int>(levelfile), width * height, &ids[0][0]);
        for (int y = 0; y < height; ++y) {
            for (int x = 0; x < width; ++x) {
                tiles.push_back(getTile(ids[x][y], sf::Vector2f(x * Tile::SIZE, y * Tile::SIZE)));
                std::cout << ids[x][y] << " ";
            }
            std::cout << std::endl;
        }
        levelfile.close();
    }
}

这就是我创建关卡的方式:

level = std::unique_ptr<Level>(new Level("data/maps/test.txt", 15, 9));

下面是控制台中的输出:

2 2 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 1 1 1 1 1 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1 1 1 1 1 1 1 1

如您所见,内容与test.txt相同,但顺序错误。

原因是您交换了数组的维度。而不是

int ids[15][9];

。这是 15 行 9 个元素,你想要

int ids[9][15];

。这是 9 行 15 个元素。声明中扩展数据的顺序与访问中索引的顺序相同。

编辑:。。。你也交换了。而不是

ids[x][y]

你需要

ids[y][x]

想想看,这确实可以更好地解释您获得的输出。 C++中的 2D 数组是按行存储的,这意味着最里面的数组(连续存储的数组)是具有最右边索引的数组。换句话说,ids[y][x]直接存储在ids[y][x + 1]之前,而ids[y][x]ids[y + 1][x]之间有一些空间。

如果您像读取 std::copy_n 一样读取行主数组并将其解释为列主数组,则会得到转置(由于尺寸更改而有点扭曲,但可以识别。如果你交换高度和宽度,你会看到真正的转置)。

int ids[9][15];
while (levelfile.is_open()) {
    std::copy_n(std::istream_iterator<int>(levelfile), width * height, &ids[0][0]);
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            tiles.push_back(getTile(ids[y][x], sf::Vector2f(x * Tile::SIZE, y * Tile::SIZE)));
            std::cout << ids[y][x] << " ";
        }
        std::cout << std::endl;
    }

如果你看一下,你可以看到你在第一个原始中打印了前 15 个值(需要在第一行)(以及不适合在第二行中的值)。您可以理解它开始填充行之前的行,并且您的文件首先包含该行。因此,请将地图"在侧面"加载。将高度设置为宽度 (15) 和相反的值(宽度为 9 而不是 15)。现在,您将正确加载地图。

不只是打印每一行并在第二行之前打印"endl"(每行打印为行)。你会看到这个好的。

希望它足够清楚。