MECSUtilsのMecsMappingFix_UnicodeToCP932関数によって、JIS→Unicode→Shift-JISで全角ハイフンが文字化けする問題が解決した

MECSUtils ver1.54では、文字コードを変換する時にハイフンを上手にマッピングしてくれる。

全角ハイフン(-)をJISからUnicodeへ、UnicodeからShift-JISへ変換すると、Shift-JISに変換した時に文字化けする。
たとえば電子メールを受信して何らかの処理を行い、ファイルに出力する時などに問題が発生する。

//文字化けするJISコードの全角のハイフン
jis: RawByteString = #$1B#$24#$42#$21#$5D#$1B#$28#$42; 

//JISからUnicodeに変換して表示する
Edit1.Text := MECSUtils.AnsiToUTF16(jis, 50220);

JISからUnicodeへ変換した時は問題なく表示される。

このとき全角ハイフンは’MINUS SIGN'(U+2212)になっている。

この’MINUS SIGN'(U+2212)をShift-JISに変換すると文字化けする。

type
  SJISString = type AnsiString(932);
var
  sjis: SJISString;
begin
  sjis := Edit1.Text;  //=> ?

ここで、MECSUtils.MecsMappingFix_UnicodeToCP932関数の出番である。
MECSUtils ver1.54では、文字コードを変換する時にハイフンを上手にマッピングしてくれる。

sjis := MECSUtils.MecsMappingFix_UnicodeToCP932(Edit1.Text); //=> -

これでハイフンが文字化けする問題は解決した。

DEKO様、MECSUtilsの修正ありがとうございました。<(_ _)>

Delphi XEとC++Builder XEで「々」の動作を確認しました。

.NET Framework 2.0以降では「々」の位置を間違えるらしい。(「愛が重ならない.NET Framework 2.0 – 新日々此何有哉」より。)

Console.WriteLine("{0}", "愛々,1,2,3".IndexOf(",")); //=> 1

Delphi XEとC++Builder XEで動作を確認しました。

# .Net FrameworkのIndexOfはインデックスが0から始まりますが、
# Delphi/C++BuilderのPosはインデックスが1から始まります。

Delphi XEの場合

Writeln(Pos('愛', '愛々,1,2,3')); //=>1
Writeln(Pos('々', '愛々,1,2,3')); //=>2
Writeln(Pos(',', '愛々,1,2,3'));  //=>3
Writeln(Pos('1', '愛々,1,2,3'));  //=>4

C++Builder XEの場合

std::cout << UnicodeString("愛々,1,2,3").Pos("愛") << std::endl; //=>1
std::cout << UnicodeString("愛々,1,2,3").Pos("々") << std::endl; //=>2
std::cout << UnicodeString("愛々,1,2,3").Pos(",") << std::endl; //=>3
std::cout << UnicodeString("愛々,1,2,3").Pos("1") << std::endl; //=>4

Delphi XEとC++Builder XEは問題ないようです。
(.NET Frameworkは詳しくないので、勘違いがあるかもしれません。)

旧Delphi/C++BuilderからUnicodeへのマイグレーションのノウハウとして「文字列の処理にMECSUtilsを使えるところはできるだけ使う」というはどうだろう。

旧Delphi/C++BuilderからUnicodeへのマイグレーションのノウハウとして「文字列の処理にMECSUtilsを使えるところはできるだけ使う」というはどうだろう。

MECSUtilsはAnsi/Unicodeの両方に対応しているので、MECSUtilsを使っている部分に関してはAnsi/Unicodeを気にする必要がない。よね?

C++Builder 2010によるひらがな・カタカナの変換

4/21 – Webセミナー「Delphi / C++Builder 旧バージョンからの移行」で質問があったひらがな・カタカナの変換方法。

C++ Builder Tipにも「全角・半角・ひらがな・カタカナの変換」の記事がありますが、AnsiStringなので古いですね。
後で修正します。

UnicodeStringなら次のようになります。
プロジェクトの設定で、「_TCHARのマップ先」を「wchar_t」に設定しています。

#include <boost/scoped_array.hpp>

UnicodeString text = L"変換する文字列";
//DWORD flags = LCMAP_FULLWIDTH; //全角文字にします。
//DWORD flags = LCMAP_HALFWIDTH; //半角文字にします。
//DWORD flags = LCMAP_HIRAGANA; //ひらがなにします。
  DWORD flags = LCMAP_KATAKANA; //カタカナにします。

const int size = text.Length() + 1;
boost::scoped_array<wchar_t> s(new wchar_t[size]);
ZeroMemory(s.get(), size);
LCMapString(GetUserDefaultLCID(),
            flags,
            text.c_str(),
            size,
            s.get(),
            size);
UnicodeString newtext = s.get();