从 txt 文件读取时,我的程序不会移动到下一行

My program won't move to next line when reading from a txt file

本文关键字:移动 一行 读取 文件 txt 程序 我的      更新时间:2023-10-16

我一直在youtube上学习如何创建磁贴图。

我的代码与教程相同,我甚至使用相同的IDE。

然而,当程序从文本文件中读取时,它似乎无法识别行尾:

#include<SFML/Graphics.hpp>
#include<iostream>
#include<fstream>
#include<cctype>
#include<string>
using namespace std;
int main()
{
ifstream openfile("map1.txt");
sf::Texture tileTexture;
sf::Sprite tiles;
sf::Vector2i map[500][200];
sf::Vector2i loadCounter = sf::Vector2i(0, 0);
if(openfile.is_open())
{
    string tileLocation;
    openfile >> tileLocation;
    tileTexture.loadFromFile(tileLocation);
    tiles.setTexture(tileTexture);
    while(!openfile.eof())
    {
        string str;
        openfile >> str;
        char x = str[0], y = str[2];
        if(!isdigit(x) || !isdigit(y))
            map[loadCounter.x][loadCounter.y] = sf::Vector2i(-1, -1);
        else
            map[loadCounter.x][loadCounter.y] = sf::Vector2i(x - '0', y - '0');
        if(openfile.peek() == 'n')
        {
            loadCounter.x = 0;
            loadCounter.y++;
        }
        else
            loadCounter.x++;
    }
    loadCounter.y++;
}

我认为这可能是映射数组太小了我的文本文件,所以我增加了它,但得到了相同的错误或堆栈溢出错误。

就像我在执行程序时看到的那样,它增加了loadCounter.x,但没有增加loadcounter.y

这是我的文本文件,抱歉,如果这里的换行是有问题的(预览显示换行,所以如果你需要一个更好的文本文件的表示,请让我知道我怎么能做到这一点,谢谢)。

在这里给出一个简短的描述,该文件包含要加载的图像的名称和以40X25组为数组的"坐标"集。

Tileset.jpg

x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
0,1 0,1 0,1 0,1 0,1 0,1 0,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
0,1 0,1 0,1 0,1 0,1 0,1 0,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
0,1 0,1 0,1 0,1 0,1 0,1 0,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
0,1 0,1 0,1 0,1 0,1 0,1 0,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
0,1 0,1 0,1 0,1 0,1 0,1 0,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
0,1 0,1 0,1 0,1 0,1 0,1 0,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x
x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x 1,1 1,1 1,1 1,1 x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x x,x

我在构建时得到这个错误。

在天使最后的十字军东征。exe中的0x0006A30D第一次机会异常:0xC0000005:访问违反写入位置0x0022003C。在天使最后的十字军东征。exe中0x0006A30D的未处理异常:0xC0000005:访问违反写入位置0x0022003C.

有两个问题在我的脑海中是文本文件只是太大,需要一个更大的地图数组?或者我的文本文件中有错误,导致代码错过新行或寻找新行的错误标识符的代码?

有两件事很明显:

sf::Vector2i map[500][200];

main()的自动变量空间中声明 100 - 1000 sf:: Vector2i对象。根据您平台上的本地堆栈空间配置,这可能会有问题。例如,要消耗1MB的堆栈空间,每个对象只需要大约11 字节的空间。你最好把它放在堆上或给数组静态链接(例如:一个全局变量或声明为static)。要把它放在堆上,使用std::array<>std::vector<>,如下所示:

#include <vector>
#include <array>
int main()
{
    std::vector<std::array<sf::Vector2i,200>> map(500);
    ....

我会诚实地选择一个不同的名字,顺便说一句,因为map在任何现代c++程序中都很容易等同于/作为std::map<>。我把这个留给你。

但我相信真正的罪魁祸首,即使你解决前面的问题是:

while(!openfile.eof())

这是错误的。阅读本文可以更好地理解为什么。由于不在循环中检查IO结果,最后的字符串提取将失败,从而留下一个空字符串,然后使用未受保护的operator[]访问该字符串。具体来说,这样的:

// after last successful string has been read, eof-bit is still not set...
while(!openfile.eof())
{
    string str;
    openfile >> str; // ... until this fails (which it will)
    char x = str[0], y = str[2]; // this this, invokes undefined behavior

如果你真的想每行都正确地执行这个操作,以确保你不会越界,那么像这样的操作可能是首选的:

std::ifstream openfile("map1.txt");
if (!openfile.is_open())
    return EXIT_FAILURE;
sf::Texture tileTexture;
sf::Sprite tiles;
// TODO: this should be checked as well
openfile >> tileLocation;
tileTexture.loadFromFile(tileLocation);
tiles.setTexture(tileTexture);
// our tile map.
std::vector<std::vector<sf::Vector2i>> mymap;
std::string line;
while (std::getline(openfile,line))
{
    std::vector<sf::Vector2i> row;
    std::istringstream iss(line)
    std::string str;
    while (iss >> str && str.length() >=3)
    {
        char x = str[0], y = str[2];
        if(!isdigit(x) || !isdigit(y))
            row.push_back(sf::Vector2i(-1, -1));
        else
            row.push_back(sf::Vector2i(x - '0', y - '0'));
    }
    if (!row.empty())
        mymap.emplace_back(row);
}

这有一个缺点,即行宽度可能可变(这可能是可以的,这取决于您在代码中如何处理)。读取的行数如下:

mymap.size()

,任意给定行中对的个数为:

mymap[rownum].size()
不管怎样,我希望你能从中有所收获。祝你好运。