2

我正在做一个文件阅读课。它应该在构造时使用给定的字符串打开文件,并根据调用的构造函数使用提供的第二个字符串来跳过文件到给定字符串之后的行。

这是我的代码:

SnakeFileReader::SnakeFileReader(string filePath)
{
    fileToRead_.open(filePath.c_str(), ios::in);
}
SnakeFileReader::SnakeFileReader(string filePath, string startString)
{
    fileToRead_.open(filePath.c_str(), ios::in);

    string toFind;

    while (toFind != startString  && !fileToRead_.eof())
    {
        fileToRead_ >> toFind;
    }
}
string SnakeFileReader::ReadLine()
{
    string fileLine;

    if (!fileToRead_.fail() && !fileToRead_.eof())
        fileToRead_ >> fileLine;

    return fileLine;
}
int SnakeFileReader::ReadInt()
{
    string fileLine = "";

    if (!fileToRead_.fail() && !fileToRead_.eof())
        fileToRead_ >> fileLine;

    int ret;

    istringstream(fileLine) >> ret;

    return ret;
}
SnakeFileReader::~SnakeFileReader()
{
    fileToRead_.close();
}

我遇到的问题是在第二个构造函数中我遇到了分段错误。一旦我声明了一个字符串,我就会在读取行函数中遇到另一个分段错误。

[编辑] 这是请求的额外代码。我正在制作一个“贪吃蛇游戏”作为我学位第一年的一部分。我希望游戏读取和保存文件而不是硬编码变量值。我最终会大量使用这个类来设置游戏中的关卡。然而,这里有几行应该演示我打算如何使用这个类:

//Level.cpp
std::string fileToRead = "resources/files/level1.txt";
SnakeFileReader sfr(fileToRead);
std::string mapFilePath = sfr.ReadLine();
ImageFile(mapFilePath).load(map_layout);
mapWidth_ = sfr.ReadInt();
mapHeight_ = sfr.ReadInt();
level_cell_size_ = sfr.ReadInt();

map_ = new TileData*[mapWidth_];

for (int i = 0; i < mapWidth_; i++)
{
    map_[i] = new TileData[mapHeight_];
}

文件布局:

resources/images/Map1_Layout.bmp
40
30
20

类声明:

#ifndef SNAKE_FILE_READER_HPP
#define SNAKE_FILE_READER_HPP

#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;
class SnakeFileReader
{
    public:
        SnakeFileReader(string filePath);
        SnakeFileReader(string filePath, string startString);
        ~SnakeFileReader();
        string ReadLine();
        int ReadInt();
    private:
        ifstream fileToRead_;
};
#endif // SNAKE_FILE_READER_HPP
4

2 回答 2

0

我不确定你的构造函数,但 ReadLine() 的问题是你试图返回一个自动变量的内存地址,当你退出函数时它被破坏了。

最简单的解决方法是删除返回值上的“&”,然后只返回一个字符串。但是如果你决定返回一个内存地址,试试这个:

string *SnakeFileReader::ReadLine()
{   
string *fileLine = new string;

if (!fileToRead_.fail() && !fileToRead_.eof())
    fileToRead_ >> *fileLine;

return fileLine;
}

这将动态分配字符串并传回指针。不同之处在于,当您离开其范围时,动态变量不会自动销毁。在您自己删除它之前,该字符串仍将存在于堆中(当您完成它时,您必须记住这样做)。

于 2013-04-01T00:28:48.867 回答
0

在 ReadLine 函数中,您返回对分配在函数堆栈上的变量的引用。您正在破坏堆栈,可能会发生疯狂的事情。你的编译器应该已经警告你了。

于 2013-04-01T00:31:47.347 回答