トップ回答者
シリアライズ化処理のマルチバイト化について

質問
-
古い環境になるのですが、VisualStudio2003でMFCアプリ(SDIタイプ)を作成しています。
標準で挿入されているDocumentクラスのSerialize関数で以下のように現在なっています。
if (ar.IsStoring())
{
for(i=0;i<PARA_MAX;i++)ar<<para_edit_name[i];
} else {
for(i=0;i<PARA_MAX;i++)ar>>para_edit_name[i];
}
para_edit_name[i]はCString型です。
ファイルに保存を選んだ時にpara_edit_name[]の文字列を全てファイルに
保存するという物です。
問題はVS2003は文字コードがデフォルトでマルチバイトなのですが、上記の
アプリがWindows7でことごとく日本語表示の部分が文字化けします。
文字コードがUnicodeになっていないからだと思うので、Unicode化対応を
しているのですが、上記のコードのままだと保存されたテキストファイルは
Unicode文字列で保存されてしまいますので、不都合なのです。
数多くの保存されたテキストファイルは通常のマルチバイトで保存されている
のでこのシリアライズ処理の保存&読込みをマルチバイトにしたいのですが、
どうやればいいのかわかりません。
SDI/MDIタイプのアプリは作成した事がないので無知識で困ってます。
どなたか、教えてもらえないでしょうか。
回答
-
CStringAが使えるのであれば、一回CStringAの変数に入れてからCStringのコンストラクタを介してpara_edit_name[i]に入れてみてはどうでしょうか?
つまり
for (i = 0; i < PARA_MAX; ++i)
{
if (ar.IsLoading()) {
CStringA temp;
arr >> temp;
para_edit_name[i] = CString(temp);
}
else if (ar.IsStoring()) {
arr << CStringA(para_edit_name[i]);
}
}
わんくま同盟[http://blogs.wankuma.com/blue/]- 回答としてマーク shimpo 2010年3月29日 5:04
すべての返信
-
そういう事です。
プロジェクト全体はUnicode文字セットにしています。
表示関係は全て処理して文字化けは直ったのですが、ファイルI/Oは
マルチバイトでないと都合悪いんです。
wcstombs()で変換して下記のようにやってみたんですが、警告が出ますし
警告無視して実行しても保存されたファイル内容もおかしいんです。
char buf[PARA_MAX];
for(i=0;i<PARA_MAX;i++) {
memset( buf, 0, PARA_MAX );
wcstombs( buf, para_edit_name[i], PARA_MAX );
ar<<buf; ←ここで警告が出る。
}
ar<<CSting型はOKなのにar<<char型はダメなんですね。
シリアライズの知識が無いので、ar<<・・・の使い方もどうもよくわかりません。CStinrgAってVS2003のMSDNで検索しても出てきませんけどどういう型なんでしょう?
- 編集済み shimpo 2010年3月29日 4:12
-
マルチバイト文字セットのときのCStringのシリアライズを自前で記述すると
1.バイト数をバイナリで出力(たぶんint型)
2.バイト数分出力
ということになります。
よって
>ar<<buf; ←ここで警告が出る。
は1バイトずつループで出力しないといけません。
# bufはchar*型なのでchar型ではない。
ひょっとするとCByteArrayのSerializeで行けるかも。
以下検証なしで、適当。
if (ar.IsStoring()) {
CByteArray ba;
int lenght = wsctombs(NULL, para_edit_name[i], 0);
ba.SetSize(lenght + 1);
wsctombs(ba.GetData(), para_edit_name[i], lenght + 1);
ba.SetSize(lenght);
ba.Serialize(ar);
}
else if (ar.IsLoading()) {
CByteArray ba;
ba.Serialize(ar);
ba.SetAtGrow(ba.GetSize(), NULL);
para_edit_name[i] = CString(ba.GetData());
}
わんくま同盟[http://blogs.wankuma.com/blue/]- 編集済み 蒼の洞窟 2010年3月29日 4:14 修正
-
-
CStringAが使えるのであれば、一回CStringAの変数に入れてからCStringのコンストラクタを介してpara_edit_name[i]に入れてみてはどうでしょうか?
つまり
for (i = 0; i < PARA_MAX; ++i)
{
if (ar.IsLoading()) {
CStringA temp;
arr >> temp;
para_edit_name[i] = CString(temp);
}
else if (ar.IsStoring()) {
arr << CStringA(para_edit_name[i]);
}
}
わんくま同盟[http://blogs.wankuma.com/blue/]- 回答としてマーク shimpo 2010年3月29日 5:04