スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

私だけ!? VC++のfstreamの挙動の話

今回バイナリを読みつつ一部を書き換える、というコードを組んだのですが、
fstreamヘッダにあるfstreamクラスを使用する場合におかしな挙動があったのでここに残しておきます。

環境
Windows7 64bit
Visual Studio 2012


単刀直入に言うと
fstream#read関数を使った後にfstream#write関数が使えない!

例えばこうですね。
std::fstream patch("Hoge.dat", std::ios::in|std::ios::out|std::ios::binary);
while(true){
int compare;
patch.read( (char*)&compare, sizeof(int) );
if(compare == 0x0A){
int hex = 0x0B;
patch.write( (char*)&hex, sizeof(int) );
}
if(patch.fail()) break;
}


Hoge.datの中に0x0Aという価を見つけた時に、次の価を0x0Bで上書きする例です。
この場合私の環境ではwrite関数を呼び出しているにもかかわらず上書きがなされない(元の価のまま)という挙動を起こしました。

うーん、私だけなのかな…。

なお、このパターンでは適用できませんが、
fstream#seekg関数を使用してからのwrite関数ならばうまく書き込んでくれました。


gccでコンパイルしたバイナリなら普通に動きました。
早くVisualStudio2013を使え…ということでしょうか。


以下実際のコード垂れ流しです。
/*-- ヘッダの一部 --*/
enum Items {
NORMAL = 0x0a,
BURST = 0x0b,
SHOTGUN = 0x0c,
MACHINEGUN = 0x0d,
TIME_STOP = 0x0e,
CLOCK_DOWN = 0x0f
};

typedef int bin_t;
static const size_t BIN_SIZE = sizeof(bin_t);
static const int ENCRYPT_NUMS[];

/*-- cpp --*/
const int ItemHelper::ENCRYPT_NUMS[] = { 10, 2, 5, 8, 12, 3 };

void ItemHelper::writeItemStatus(Items index, bool flag){
std::fstream rewrite(ITEM_FILE, std::ios::in|std::ios::out|std::ios::binary);
//bool found = false;

//while(true){
// bin_t comp;
// rewrite.read( (char*)&comp, BIN_SIZE );
// if(rewrite.fail()) break;

// if( comp == (bin_t)index ){
// // データの書き出し
// bin_t encryptValue = (bin_t)( (int)flag * ENCRYPT_NUMS[index-0x0a] ); // 暗号化
// rewrite.write( (char*)&encryptValue, BIN_SIZE );

// found = true;
// break;
// }else{
// // 読み飛ばし
// rewrite.read( (char*)&comp, BIN_SIZE );
// }
//}

//if(!found)
// throw std::string("Index Not Found in Binary");

/* 動かんので妥協策 */
rewrite.seekg( BIN_SIZE*( ((int)index-0x0a)*2+1 ));
bin_t encryptValue = (bin_t)( (int)flag * ENCRYPT_NUMS[index-0x0a] );
rewrite.write( (char*)&encryptValue, BIN_SIZE);
}

スポンサーサイト
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。