1

I have been following a youtube tutorial for creating a tilemap.

My code is identical to the tutorial I am even using the same IDE.

However as the program reads from the text file it appears to not recognize the end of line:

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

I thought it could be that the map array was too small for my text file so i increased it but got the same error or a stack overflow error.

As I see it in stepping out the program it increments loadCounter.x but never Increments loadcounter.y

Here's my textfile, sorry if the word wrap here is problematic (preview is showing the newlines so if you need a better representation of the txt file please let me know how i could do that thanx).

To give a short description here the file contains the name of the image to be loaded and sets of "coords" in an array of 40X25 sets.

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

i get this error when building.

First-chance exception at 0x0006A30D in Angels Last Crusade.exe: 0xC0000005: Access violation writing location 0x0022003C. Unhandled exception at 0x0006A30D in Angels Last Crusade.exe: 0xC0000005: Access violation writing location 0x0022003C.

There are two questions in my mind is the text file just too big requiring a much larger map array? or is there an error in my text file causing the code to miss the new line or the code looking for the wrong identifier of a new line?

manlio
  • 18,345
  • 14
  • 76
  • 126
FPSHero
  • 11
  • 1

1 Answers1

4

Two things are immediately apparent:

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

This declares one-hundred-thousand sf:: Vector2i objects in the automatic variable space of main(). Depending on your local stack space configuration on your platform, this may be problematic. For example, to consume 1MB to stack space would only require about 11 bytes of space per object. You would be better off putting this on the heap or giving the array static linkage (ex: a global variable or declared as static). To put it on the heap, use a std::vector<> of std::array<>, like this:

#include <vector>
#include <array>

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

I would honestly choose a different name, btw, as map in any modern C++ program is easily equated to/as std::map<>. I leave that to you.

But I believe the real culprit even if you address the prior item is this:

while(!openfile.eof())

This is s wrong. Read this to better understand why. By not checking your IO results within your loop the last string extraction will fail, thereby leaving you with an empty string, which you then access using the unprotected operator[]. Specifically, this:

// 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

If you really want to do this correctly per line to ensure you don't overleap your bounds, something like this would likely be preferred:

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

This has the one drawback of the potential for a variable row width (which may be ok, depending on how you handle that in your code). The number of rows read is simply:

mymap.size()

and the number of pairs in any given row is:

mymap[rownum].size()

Anyway, I hope you get something out of it. Best of luck.

Community
  • 1
  • 1
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • thanx @WhozCraig, i am able to get something to draw to screen however i havent figured out how to draw a map that has more rows than pairs it gives error Debug assertion failed, ..., Expression: vector subscript out of range.... however if the pairs are more than the rows it compiles fine. – FPSHero May 21 '14 at 10:51
  • @user3659128 that would be the part about making sure you stay within the boundaries of your map file. The code I posted (the bottom) for any given row, will have a specific number of pairs slurped from the input file. If the image you're mapping doesn't match, you'll have to take an alternative action once you run out of pairs. Honestly, I don't know jack about the video work your doing; but I *do* know the standard lib, thus why the read-alternative was so direct to come up with. – WhozCraig May 21 '14 at 10:55
  • i think you've lost me. the errors come about by editing the input file not the code. and the text is the image only by changing the pairs ie x,x -> 1,1 it will crop a section out of the tileset and print onscreen. i'm at a loss as to how to get your code to work with more rows than sets of pairs. as it is it works fine with more pairs than rows. unfortunately this prints out an image that is taller than wide which is opposite to most monitors – FPSHero May 21 '14 at 11:06