1

I'm making a tiling engine/game in C++. What I am struggling with is that I can't quite figure out how to load and manipulate integer data from a file.

Here is the mapfile.map:

[jbs@dmb-gaming-laptop ~]$ cat cpp/adventures_of_ironville/mapfile.map 
0000001111101111
0000111000020000
1100000000000000
0100200000111000
0110000000111200
0010002200111120
2010002220111111
0010022200001111
0000001111101111
0000111000020000
1100000000000000
0100200000111000
0110000000111200
0010002200111120
2010002220111111
0010022200001111
[jbs@dmb-gaming-laptop ~]$ 

This is to be the level in my game. Now, for the code I'm struggling with:

bool World::loadLevelFromDisk(std::string pathToMapFile)
{
    //Our file object
    std::ifstream file(pathToMapFile);

    //Store contents of file
    char tempData;

    if (!file.is_open()) {
        //Error...
        return false;
    } else { //File is ready to use
         while (!file.eof())
        {
            //Grab one character.
            tempData = file.get();

            //Convert that character
            //to ascii integer.
            int data = tempData - 48;

            //std::vector used elsewhere,
            //which must take an int.
            currentLevel.push_back(data);

            //Why does this output a bunch of -38's?
            //expected output is to be identical to the
            //mapfile.map.
            std::cout << data;
        }
    }
}

The output of that last std::cout:

0000001111101111-380000111000020000-381100000000000000-380100200000111000-380110000000111200-380010002200111120-382010002220111111-380010022200001111-380000001111101111-380000111000020000-381100000000000000-380100200000111000-380110000000111200-380010002200111120-382010002220111111-380010022200001111-38-49

How can I read the integer data from file?? I have spent a great deal of time trying out different solutions, from string streams to boost::lexical_cast and I haven't found an answer that works. This is the closest I have gotten to the intended result, which is reading the file as integers so it can be manipulated elsewhere. All help is greatly appreciated!

JohnBobSmith
  • 159
  • 1
  • 3
  • 10

2 Answers2

3

The -38 is actually the line feed (\n character) You read 10 (ascii code for NewLine, and then calculate 10 - 48)

Just omit them with this modification in your code:

...
tempData = file.get();
if ( tempData == '\n' || tempData =='\r' ) continue;
...

The \r character is only for windows, but doesn't hurt to be extra careful.

Another approach would be to simply ignore anything that's not a number, in that case the condition would be:

if ( tempData < '0' || tempData > '9' ) continue;
adnan_e
  • 1,764
  • 2
  • 16
  • 25
  • Wow! Thank you all so much! changing the eof loop condition removed the extraneous -49, and doing what was suggested here fixed my issue! – JohnBobSmith Jul 08 '16 at 22:34
1

The first thing I noticed about your code is you are looping using !file.eof() This is almost always a bad thing:

See: Why is iostream::eof inside a loop condition considered wrong?

Other than that you are not checking to select only the character codes you want to convert (as mentioned in other answers).

std::vector<char> currentLevel;

bool loadLevelFromDisk(std::string pathToMapFile)
{
    //Our file object
    std::ifstream file(pathToMapFile);

    if(!file.is_open())
    {
        //Error...
        return false;
    }

    //File is ready to use

    //Store contents of file
    char tempData;

    // grab one char
    while(file.get(tempData)) // never loop on eof()
    {
        // you only get here if file.get() was a success

        if(tempData < '0' || tempData > '9')
            continue; // ignore irrelevant characters

        //Convert that character
        //to ascii integer.
        int data = tempData - '0'; // more portable

        //std::vector used elsewhere,
        //which must take an int.
        currentLevel.push_back(data);

        std::cout << data;
    }

    return true; // don't forget to indicate success
}

Also you forgot to return true if the function succeeded. This error would have been detected if you increase the warning level of the compiler (I use -Wall -Wextra -pedantic-errors with GCC).

Galik
  • 47,303
  • 4
  • 80
  • 117