« トラックボールについて | メイン | D2 バージョン 2.0.6 公開 »

C++Builder 2009のTMemIniFileとエンコードの挙動を調べた

C++Builder 2009のTMemIniFileとエンコードの挙動を調べた。

結論から先に言うと、エンコードを指定する場合は「TEncoding::Unicode」を使うこと。
TEncoding::UTF8やEncoding:UTF7を使うと、不可思議な挙動に悩まされる。

エンコードを指定しないC++Builder 2007と同じ書き方。

//書き込み
std::unique_ptr<TMemIniFile> ini(new TMemIniFile(path));
ini->WriteString(L"日本語", L"こんにちは", L"こんにちは");
ini->WriteString(L"中国語", L"こんにちは", L"你好");
ini->UpdateFile();

ファイルには、ANSIのデフォルトのコードページ(Shift_JIS)で保存される。
したがって、文字化けする。

//読み込み
std::unique_ptr<TMemIniFile> ini(new TMemIniFile(path));
ini->ReadString(L"日本語", L"こんにちは", "no data"); //=> こんにちは
ini->ReadString(L"中国語", L"こんにちは", "no data"); //=> ?好

エンコードにTEncoding.Unicodeを指定する書き方。
リトルエンディアンバイトオーダーのUTF-16で保存される。
ファイルには16進数 FFFE のバイトオーダーマークが付く。

//書き込み
std::unique_ptr<TMemIniFile> ini(new TMemIniFile(path, TEncoding::Unicode));
ini->WriteString(L"日本語", L"こんにちは", L"こんにちは");
ini->WriteString(L"中国語", L"こんにちは", L"你好");
ini->UpdateFile();

//読み込み
std::unique_ptr<TMemIniFile> ini(new TMemIniFile(path, TEncoding::Unicode));
ini->ReadString(L"日本語", L"こんにちは", "no data"); //=> こんにちは
ini->ReadString(L"中国語", L"こんにちは", "no data"); //=> 你好

書き込み、読み込みともに問題なく動作する。

なお、ファイルにバイトオーダーマークが付いているので、エンコードを指定しなくても、自動的に識別してくれる。

std::unique_ptr<TMemIniFile> ini(new TMemIniFile(path));
ini->ReadString(L"日本語", L"こんにちは", "no data"); //=> こんにちは
ini->ReadString(L"中国語", L"こんにちは", "no data"); //=> 你好

エンコードにTEncoding::UTF8を指定する書き方。
UTF-8形式で保存される。
ファイルには、16進数 EFBBBF のバイトオーダーマークが付く。

//書き込み
std::unique_ptr<TMemIniFile> ini(new TMemIniFile(path, TEncoding::UTF8));
ini->WriteString(L"日本語", L"こんにちは", L"こんにちは");
ini->WriteString(L"中国語", L"こんにちは", L"你好");
ini->UpdateFile();

//読み込み
std::unique_ptr<TMemIniFile> ini(new TMemIniFile(path, TEncoding::UTF8));
Memo1->Lines->Add(ini->ReadString(L"日本語", L"こんにちは", "no data")); //=> こんにちは
Memo1->Lines->Add(ini->ReadString(L"中国語", L"こんにちは", "no data")); //=> 你好 / ?好

ここで、奇妙な動作になる。

ファイルが存在しないとき、つまり新規保存になるときは正しく、UTF-8で保存される。
ところが、すでにファイルが存在するときには、ANSIのデフォルトのコードページ(Shift_JIS)で保存されてしまう。

TEncoding::UTF8ではなくTEncoding::UTF7を使っても、同様の現象が起こる。

トラックバック

このエントリーのトラックバックURL:
http://www.gesource.jp/mt/mt-tb.cgi/837

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

About

2008年10月13日 18:17に投稿されたエントリーのページです。

ひとつ前の投稿は「トラックボールについて」です。

次の投稿は「D2 バージョン 2.0.6 公開」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

Powered by
Movable Type 3.35