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

时间:2014-05-21 07:20:00

标签: c++ fstream sfml access-violation

我一直在关注创建tilemap的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

这是我的文本文件,对不起,如果这里的自动换行有问题(预览显示新行,所以如果您需要更好地表示txt文件,请让我知道我怎么能做到这一点)。

为了在这里给出一个简短的描述,该文件包含要加载的图像的名称和&#34; coords&#34;在一组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

构建时出现此错误。

Angels Last Crusade.exe中0x0006A30D的第一次机会异常:0xC0000005:访问冲突写入位置0x0022003C。 Angels Last Crusade.exe中0x0006A30D处于未处理的异常:0xC0000005:访问冲突写入位置0x0022003C。

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

1 个答案:

答案 0 :(得分:4)

有两件事情是显而易见的:

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

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

#include <vector>
#include <array>

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

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

但我相信真正的罪魁祸首即使你解决了之前的项目是这样的:

while(!openfile.eof())

这是错的。 Read this to better understand why。通过不在循环中检查IO结果, last 字符串提取将失败,从而为您留下一个空字符串,然后使用不受保护的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()

无论如何,我希望你能从中得到一些东西。祝你好运。