2

ファイル読み取りクラスを作成しています。構築時に、指定された文字列でファイルを開き、呼び出されたコンストラクターに応じて、指定された文字列の後の行までファイルをスキップするために指定された 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();
}

私が抱えている問題は、2 番目のコンストラクターでセグメンテーション違反が発生することです。文字列を宣言するとすぐに、read line 関数で別のセグメンテーション違反が発生します。

[編集] リクエストされた追加のコードは次のとおりです。私は学位の最初の年の一部として「スネーク ゲーム」を作っています。変数値をハードコードするのではなく、ゲームでファイルを読み取って保存するようにしたい。最終的には、ゲーム内のレベルを設定するためにこのクラスを多用します。ただし、このクラスの使用方法を示す必要があるいくつかの行を次に示します。

//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 に答える