C++ 从文件加载数组

C++ 从文件加载数组,c++,arrays,file,sfml,C++,Arrays,File,Sfml,我试图加载一个整数文件,将它们添加到二维数组中,遍历数组,并根据当前索引中的整数(Tile ID)将Tile添加到我的级别。我的问题似乎是数组的加载/迭代顺序错误。这是我从中加载的文件: 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

我试图加载一个整数文件,将它们添加到二维数组中,遍历数组,并根据当前索引中的整数(Tile ID)将Tile添加到我的级别。我的问题似乎是数组的加载/迭代顺序错误。这是我从中加载的文件:

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

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

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

int ids[15][9];
…这是15行9个元素,你想要

int ids[9][15];
…这是由15个元素组成的9行。声明中数据块的顺序与access中索引的顺序相同

编辑:…您也交换了它。而不是

ids[x][y]
你需要

ids[y][x]
想想看,这更能解释你得到的结果。2D数组在C++中存储行主要,这意味着最里面的数组(连续存储的数组)是最右边的索引数组。换句话说,
ids[y][x]
直接存储在
ids[y][x+1]
之前,而
ids[y][x]
ids[y+1][x]
之间有一些空间


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

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

不只是打印每一行和第二行之前的“endl”(每一行打印为行),您将看到这个ok

希望它足够清晰。

intids[9][15];
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;
    }
while(levelfile.is_open()){ std::copy_n(std::istream_迭代器(levelfile),宽度*高度,&id[0][0]); 对于(int y=0;y顺便说一句,带前导下划线的标识符是为编译器保留的。那么,在构造函数中传递的变量的命名约定是什么?没有真正的命名约定。有些人使用尾随下划线,另一些人使用带“m_”的成员变量前缀。此外,约定是使用构造函数的初始值设定项列表。That输出“2 1 1 4067280”,然后它崩溃。是
\u width==15
\u height==9
?啊。第二看。你也在访问中交换了它们。是的,std::cout
ids[y][x]
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;
    }