ユニコードで、半角⇔全角を置き換えるには

解決


マホメット・エラー  2008-03-12 03:01:58  No: 67830

MFC/.NET2005です。
ユニコードで、CString型文字列を、半角⇔全角と置き換えるには、どうしたらいいのでしょうか。
くぐると、MBCSでは、いろいろヒットするのですが、ユニコードについては見つかりません。

よろしくお願いします。


yoh2  2008-03-12 06:07:16  No: 67831

LCMapString()はいかが? MBCS、UNICODE両方いけます。

それとは別に自前で変換するなら、半角カナ、全角英数はU+FF**に集まっているので、
そのの文字コード表を見ながら変換方法を考えるとよいです。


マホメット・エラー  2008-03-12 23:57:50  No: 67832

yoh2さん、ありがとうございます。

MBCSで、LCMapString()を使っていたので、そのまま置き換えてみました。

CString ss1=_T("ケケケケケケ");
int length = ss1.GetLength () * 2 + 1;

TCHAR* pDest = (TCHAR*)GlobalAlloc(GMEM_FIXED, length);
LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_FULLWIDTH, (LPCSTR)ss1, ss1.GetLength () + 1, pDest, length);
ss1 = (LPCSTR)pDest; GlobalFree(pDest);

ところが、ユニコードライブラリを使っていると、(LPCSTR)ss1が通らないらしく、LCMapStringの行で、
'CString' から 'LPCSTR' に変換できません。
というエラーになります。

試しに
LPCSTR lpc = ss1;
を追加すると、やはり同じエラーになります。

初歩的なことだと思うのですが、初心者でよくわかりません。
アドバイスを頂けませんでしょうか。


Blue  2008-03-13 00:11:15  No: 67833

>ところが、ユニコードライブラリを使っていると、(LPCSTR)ss1が通らないらしく、LCMapStringの行で、
>'CString' から 'LPCSTR' に変換できません。
>というエラーになります。
もともとのコードからCStringを使っているのにもかかわらず、LPCSTRを使っていたのがまずかったのです。

CStringの場合は、LPCTSTRを使ってください。
(MBCSの場合はLPCSTRに、UNICODEの場合はLPCWSTRになる)

というか、勝手にoperator LPCTSTRが呼ばれるので明にキャストする必要はないのですけどね。

私なら、

    CString strResult;
    const int nLength = strSrc.GetLength() * 2 + 1;
    ::LCMapString(LOCALE_USER_DEFAULT,
                  LCMAP_FULLWIDTH,
                  strSrc,
                  -1,
                  strResult.GetBuffer(nLength),
                  nLength);
    strResult.ReleaseBuffer();

こんな感じでオワ。


マホメット・エラー  2008-03-13 05:19:25  No: 67834

Blueさん、ありがとうございました。

解決しました。


マホメット・エラー  2008-03-13 05:20:01  No: 67835

解決のチェックを忘れてしまいました。


yoh2  2008-03-13 06:21:42  No: 67836

ちと気になる点が。

> int length = ss1.GetLength () * 2 + 1;

UNICODEの場合、半角→全角変換で文字数が増えることはありませんので、×2は不要かと。
カナ + 濁点が一文字になるのでむしろ減ります。
# 全角平仮名/片仮名 + 全角/半角濁点もついでに一文字になるみたいです

また、同じ理由で、MBCSでは文字数(というかバイト数)が増えなかった
全角→半角は文字数が増える可能性があるので注意して下さい。
# これまた全角かな + 濁点が一文字になるので減ることもありますが

まあ、その辺は分かってて、MBCSと両対応のソースにするために×2している、
ということでしたらごめんなさい。


マホメット・エラー  2008-03-13 18:58:53  No: 67837

yoh2さん、ありがとうございます。

> まあ、その辺は分かってて、

あまり分っていませんでした。
MBCSとの比較で、×2が必要なのかな、という疑問は頭をかすめたのですが、あまり深く考えませんでした。
たいへんありがとうございました。


コンドル  2023-10-27 08:09:30  No: 151192

見つけました。ありがとうございます。
CString ss1=_T("ケケケ ケケケ テスト");
long  nSize = LCMapString( LOCALE_SYSTEM_DEFAULT, LCMAP_FULLWIDTH, (LPCTSTR)ss1, -1, NULL, 0 );
wchar_t*  ptBuffer = new wchar_t[nSize];
LCMapString( LOCALE_SYSTEM_DEFAULT, LCMAP_FULLWIDTH, (LPCTSTR)ss1, -1, ptBuffer, nSize);
AfxMessageBox( ptBuffer );
delete[] ptBuffer;


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加