ANSI ファイルを読み書きする MFC プロジェクトがあります。アプリケーションの文字セットはUnicodeに設定されています。
補遺
私のコンテキストでは、レガシーソフトウェア間のコンバーターについて話しているため、入力ファイルと出力ファイルのエンコーディングを変更/影響する可能性はありません。予想される文字エンコーディングは、実際にはwindows-1252です。
いくつかのファイルを読み書きしているときに、 で読み書きすると、のようなめったに使用されない文字がŠ (0x8A)
に置き換えられることに気付きました。との間の範囲でどの文字が影響を受けるかを確認するためのテストファイルを作成しました。? (0x3F)
CStdioFile
0x30
0xFF
これらの文字をテストファイル(ANSI コード)にコピーしました(0x30 から 0xFF までの文字)
結果のファイルは次のようになります。
変更された文字はすべて同じ地域にあり、すべて0x3F '?'
- から0x80
まで変更されてい0x9F
ます。奇妙なことに、影響を受けなかった0x81
、0x8D
、0x90
などの例外がいくつかあります。0x9D
動作をテストするコード例:
//prepare vars
CFileException fileException;
CStdioFile filei;
CStdioFile fileo;
CString strText;
//open input file
filei.Open(TEXT("test.txt"), CFile::modeRead | CFile::shareExclusive | CFile::typeText, &fileException);
//open output file
fileo.Open(TEXT("testout.txt"), CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive | CFile::typeText, &fileException);
//read and write
BOOL eof = filei.ReadString(strText) <= 0;
fileo.Write(CStringA(strText), CStringA(strText).GetLength());
//clean up
filei.Close();
fileo.Close();
なぜそれを行うのですか?すべての文字を保持するにはどうすればよいですか?
Unicode モードを無効にすると問題は解決しますが、残念ながら私の場合はオプションではありません。
要約
以下は、受け入れられた回答から私にとって役に立ったものを抜粋したものです。
コンストラクターを呼び出すだけでからCStringW
に変換しないでください。CStringA
Unicode から "ANSI" (Windows1252) に変換する場合は、次を使用しますCW2A
。
CStringA strTextA(strText, CP_ACP)` //CP_ACP converts to ANSI
fileo.Write(strTextA, strTextA.GetLength());
さらに簡単: のCStdioFile::WriteString
代わりにメソッドを使用しますCStdioFile::WriteS
。
fileo.Open(TEXT("testout.txt"), CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive | CFile::typeText, &fileException);
fileo.WriteString(strText);