4

私はC++でOpenGLゲームを作っています。私は他の言語とは対照的に、C++にはかなり不慣れです。とにかく、私はいくつかの画像の「ベース」ディレクトリで文字列ストリームを作成します。次に、この文字列ストリームを関数パラメーターとしてコンストラクターに渡します。コンストラクターは画像ファイル名を追加してから、結果のパスを読み込もうとします。でも...

D:\CodeBlocks Projects\SnakeRoid\bin\Debug\Texts\ <-- before appending the filename
Ship01.tgacks Projects\SnakeRoid\bin\Debug\Texts\ <-- After.

明らかに正しくありません!結果はD:\ CodeBlocks Projects \ SnakeRoid \ bin \ Debug \ Texts\Ship01.tgaになります。

私のコードの関連部分:

std::stringstream concat;
std::string txtFullPath = "Path here";

...

concat.str(""); //Reset value (because it was changed in ...)
concat << texFullPath; //Restore the base path
PS = new PlayerShip(&TexMan, concat); //Call the constructor

コンストラクターのコード

PlayerShip::PlayerShip(TextureManager * TexMan, std::stringstream &path)
{
    texId = 2;
    std::cout << path.str(); //First path above
    path << "Ship01.tga";
    std::cout  << path.str(); //Second - this is the messed up one
    //Do more fun stuff
}

ストリングストリームにすでに含まれているものを「上書き」する理由を誰かが知っていますか?

4

1 に答える 1

12

なぜストリングストリームにすでにあるものを「上書き」するのか

出力は、出力バッファの「プットポインタ」位置に文字を配置するためです。新しく構築されたストリームでは、putポインターがゼロに設定されているため(追加モードで開かれたファイル出力ストリームを除く)、出力は既にバッファーにある文字を上書きします。

本当にこの方法で文字列を追加する必要がある場合は、putポインタをバッファの最後に移動する必要があります。

std::cout << p.str(); //First path above
std::stringstream path;
path.str(p.str());
path.seekp(0, std::ios_base::end); // <-- add this
path << "Ship01.tga";
std::cout << "Loading player ship from " << path.str(); 

path.str(p.str());編集:質問は編集され、編集後のコードは機能します。これは、出力操作を使用せずに(およびプットポインターを進めずに)出力バッファーを作成するために使用されなくなったためです。違いについては、 ideoneを参照してください。

いずれの場合も、文字列自体を連結できます。これにより、コードを簡単に理解できるようになります。

std::string p = path.str() + "Ship01.tga";
std::cout << p;

言うまでもなく、ファイルとパス名を処理するために、boost.filesystemがあります。

于 2012-04-30T17:44:41.593 に答える