从文件加载数组

时间:2015-01-05 22:59:34

标签: c++ arrays file sfml

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

的test.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中的内容相同,但顺序错误。

3 个答案:

答案 0 :(得分:2)

原因是你交换了数组的尺寸。而不是

int ids[15][9];

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

int ids[9][15];

...这是15行15个元素。声明中范围的顺序与访问中的索引顺序相同。

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

ids[x][y]

你需要

ids[y][x]

这样可以更好地解释你得到的输出,想一想。 C ++中的2D-Arrays存储为row-major,这意味着最内层的数组(连续存储的数组)是具有最右边索引的数组。换句话说,ids[y][x]直接存储在ids[y][x + 1]之前,而ids[y][x]ids[y + 1][x]之间有一些空格。

如果您像使用std::copy_n那样读取行主数组并将其解释为列主数组,则会获得转置(由于更改的维度而略微变形,但可以识别如此。你交换了高度和宽度,你会看到真正的转置。)

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

不仅在第二行之前打印每一行和“endl”(每行打印为行)。你会看到这个。

希望它足够清楚。