Что я могу сделать, чтобы не использовать! OpenFile.eof ()?

Я следил за учебником по платформеру allegro 5, и его файловый менеджер использует! OpenFile.eof (), и я слышал, что это не очень хорошо, и я почти уверен, что это дает мне ошибку векторного индекса вне диапазона. Могу ли я использовать что-нибудь кроме него? Также вы можете проверить мой класс слоя, если это дает мне ошибку индекса вектора вне допустимого диапазона? Я не могу понять это, и я почти уверен, что это из файлового менеджера, но я не могу сказать.

Он выводит только первую строку карты. Когда я меняю его на while (std :: getline (openFile, line)), я даже не добираюсь до std :: cout ‹< contents [i] [k] ‹< contents [i] .size () ‹< std :: endl ‹< std :: endl;

Когда я меняю его на while (std :: getline (openFile, line)), атрибуты и содержимое получают только 8 каждый.

По-прежнему нужна помощь = \

FileManager.CPP

#include "FileManager.h"


FileManager::FileManager()
{
    identifierFound = false;
}


FileManager::~FileManager()
{
}

void FileManager::LoadContent(const char *filename, std::vector<std::vector<std::string>> &attributes, std::vector<std::vector<std::string>> &contents)
{
    std::ifstream openFile(filename);
    std::string line, newLine;

    if(openFile.is_open())
    {
        while(std::getline(openFile, line))
        {
            std::stringstream str;

            if(line.find("Load=") != std::string::npos)
            {
                type = LoadType::Attributes;
                line = line.erase(0, line.find("=") + 1);
                tempAttributes.clear();
            }
            else
            {
                type = LoadType::Contents;
                tempContents.clear();
            }

            str << line;

            while(std::getline(str, newLine, ']'))
            {
                newLine.erase(std::remove(newLine.begin(), newLine.end(), '['), newLine.end());

                std::string erase = " \t\n\r"; 

                newLine.erase(newLine.find_last_not_of(erase) + 1);

                if(type == LoadType::Attributes)
                    tempAttributes.push_back(newLine);
                else
                    tempContents.push_back(newLine);

                std::cout << newLine << std::endl;
            }

            if(type == LoadType::Contents && tempContents.size() > 0)
            {
                attributes.push_back(tempAttributes);
                contents.push_back(tempContents);
            }
        }
    }
    else
    {

    }
}

void FileManager::LoadContent(const char *filename, std::vector<std::vector<std::string>> &attributes, std::vector<std::vector<std::string>> &contents, std::string identifier)
{
    std::ifstream openFile(filename);
    std::string line, newLine;

    if(openFile.is_open())
    {
        while(!openFile.eof())
        {
            std::stringstream str;
            std::getline(openFile, line); 

            if(line.find("EndLoad=") != std::string::npos && line.find(identifier) != std::string::npos)
            {
                identifierFound = false;
                break;
            }
            else if(line.find("Load=") != std::string::npos && line.find(identifier) != std::string::npos)
            {
                identifierFound = true;
                continue;
            }

            if(identifierFound)
            {

                if(line.find("Load=") != std::string::npos)
                {
                    type = LoadType::Attributes;
                    line = line.erase(0, line.find("=") + 1);
                    tempAttributes.clear();
                }
                else
                {
                    type = LoadType::Contents;
                    tempContents.clear();
                }

                str << line;

                while(std::getline(str, newLine, ']'))
                {
                    newLine.erase(std::remove(newLine.begin(), newLine.end(), '['), newLine.end());

                    std::string erase = " \t\n\r"; 

                    newLine.erase(newLine.find_last_not_of(erase) + 1);

                    if(type == LoadType::Attributes)
                        tempAttributes.push_back(newLine);
                    else
                        tempContents.push_back(newLine);

                    std::cout << newLine << std::endl;
                }

                if(type == LoadType::Contents && tempContents.size() > 0)
                {
                    attributes.push_back(tempAttributes);
                    contents.push_back(tempContents);
                }
            }
        }
    }
    else
    {

    }
}

Layer.CPP

#include "Layer.h"


Layer::Layer(void)
{
}


Layer::~Layer(void)
{
}

std::pair<int, int> Layer::SetTiles(std::string tileString)
{
    std::pair<int, int> tile;
    tile.first = atoi(tileString.substr(0, tileString.find(',')).c_str());
    tile.second = atoi(tileString.substr(tileString.find(',') + 1).c_str());
    return tile;
}

void Layer::LoadContent(std::string layerID, std::string mapID)
{
    std::string fileName = "Maps/"+mapID+".txt";
    fileManager.LoadContent(fileName.c_str(), attributes, contents, layerID);
    int indexY = 0;

    for(int i = 0; i < attributes.size(); i++)
    {
        for(int j = 0; j < contents[i].size(); j++)
        {
            if(attributes[i][j] == "SolidTiles")
            {
                solidTiles.push_back(SetTiles(contents[i][j]));
                std::cout << contents[i][j] << std::endl << std::endl;
            }
            else if(attributes[i][j] == "TileSheet")
            {
                std::cout << contents[i][j] << std::endl << std::endl;
                tileSheet = al_load_bitmap(contents[i][j].c_str());
            }
            else if(attributes[i][j] == "StartLayer")
            {
                for(int k = 0; k < contents[i].size(); k++)
                {
                    std::cout << contents[i][k] << " k: " << k << " contents: " << contents[i].size() << std::endl << std::endl;
                    if(contents[i][k] != "---")
                    {
                        std::cout << contents[i][k] << std::endl << std::endl;
                        ALLEGRO_BITMAP *tileImage;
                        Tile::State tempState = Tile::State::Passive;
                        std::pair<int, int> tile = SetTiles(contents[i][k]);

                        if(std::find(solidTiles.begin(), solidTiles.end(), tile)  != solidTiles.end())
                        {
                            tempState = Tile::State::Solid;
                        }

                        tileImage = al_create_sub_bitmap(tileSheet, tile.first * 32, tile.second * 32, 32, 32);

                        std::pair<float, float> position(k * 32, indexY * 32);

                        Tile tileInstance;
                        tiles.push_back(tileInstance);
                        tiles[tiles.size()-1].SetContent(tileImage, tempState, position);
                        std::cout << tiles.size() << std::endl;
                    }
                }
                indexY++;
            }
        }
    }
}

void Layer::UnloadContent()
{
    for(int i = 0; i < tiles.size(); i++)
        tiles[i].UnloadContent();

    al_destroy_bitmap(tileSheet);
}

void Layer::Update()
{
}

void Layer::Draw(ALLEGRO_DISPLAY *display)
{
    for(int i = 0; i < tiles.size(); i++)
        tiles[i].Draw(display);
}

map1.txt

Load=[MapProperties]

Load=[TileDimensions]
[32,32]

EndLoad=[MapProperties]

Load=[Layer1]

Load=[SolidTiles]
[2,0]
[1,0]

Load=[NullTile]
[---]

Load=[Motion]
[2,0:Static]

Load=[TileSheet]
[TileSheets/tilesheet1.png]

Load=[StartLayer]

[2,0][---][---][---][---][---][---][---][---][---][---][---][---][---][---][---]
[---][---][---][---][---][---][---][---][---][---][---][---][---][---][---][---]
[---][---][---][---][---][---][---][---][---][---][---][---][---][---][---][---]
[---][---][---][---][---][---][---][---][2,0][2,0][2,0][---][---][---][---][---]
[---][---][---][---][---][---][---][2,0][---][---][---][---][---][---][---][---]
[---][---][---][---][---][---][2,0][---][---][---][---][---][---][---][---][---]
[---][---][---][---][---][---][---][---][---][---][---][---][---][---][---][---]
[---][---][2,0][2,0][2,0][---][---][---][---][---][---][---][---][---][---][---]
[---][---][---][---][---][---][---][---][---][---][---][---][---][---][---][---]
[---][---][---][---][---][---][---][---][---][---][---][---][---][---][---][---]
[1,0][1,0][1,0][1,0][1,0][1,0][1,0][1,0][1,0][1,0][1,0][1,0][1,0][1,0][1,0][1,0]

Load=[EndLayer]
[dummy]

EndLoad=[Layer1]

Load=[PlayerPosition]
[0,0]

person user4648142    schedule 12.03.2015    source источник
comment
Больше помощи? этот ответ не помог   -  person user4648142    schedule 12.03.2015


Ответы (1)


Во-первых, настоящая проблема не в использовании file.eof(); есть случаи, когда это то, что вы хотите (хотя я не могу придумать, где это было бы в while случаях, когда это уместно, все после того, как вы уже обнаружили, что ввод не удался). Настоящая проблема в том, что код использует значение, прочитанное с помощью std::getline, без проверки его успешности. Поскольку это присутствует в вашем коде только один раз, просто используйте то же решение, что и в других циклах: while ( std::getline( ... ) ).

person James Kanze    schedule 12.03.2015
comment
Я только что добавил новую информацию. Я просто пробовал это, но теперь это даже не проходит for (int k = 0; k ‹contents [i] .size (); k ++) - person user4648142; 12.03.2015