无法正确读取文件中的整数C ++

时间:2016-07-08 22:23:15

标签: c++

我正在使用C ++制作平铺引擎/游戏。我正在努力的是,我无法弄清楚如何从文件加载和操作整数数据。

这是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 ~]$ 

这是我游戏中的关卡。现在,对于我正在努力的代码:

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

最后一个std :: cout:

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

如何从文件中读取整数数据?我花了很多时间尝试不同的解决方案,从字符串流到boost :: lexical_cast,我还没有找到有效的答案。这是我得到的最接近预期结果,即将文件作为整数读取,因此可以在其他地方操作。非常感谢所有帮助!

2 个答案:

答案 0 :(得分:3)

-38实际上是line feed\n个字符) 您阅读10(NewLine的ascii代码,然后计算10 - 48)

在代码中使用此修改省略它们:

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

\r字符仅适用于Windows,但不要格外小心。

另一种方法是简单地忽略任何不是数字的东西,在这种情况下条件是:

if ( tempData < '0' || tempData > '9' ) continue;

答案 1 :(得分:1)

我注意到你的代码的第一件事是你使用!file.eof()进行循环这几乎总是一件坏事:

请参阅: Why is iostream::eof inside a loop condition considered wrong?

除此之外,您不会选中仅选择要转换的字符代码(如其他答案中所述)。

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
}

如果功能成功,您也忘记返回true。如果您增加编译器的警告级别,则会检测到此错误(我将-Wall -Wextra -pedantic-errorsGCC一起使用。)