プロが教える店舗&オフィスのセキュリティ対策術

あるバッファに入っている文字列の文字コード(ANSI、SJIS、UNICODEなど)を判定したいのですが、色々と調べたのですが、解決しませんでした。

ANSIでもUNICODEでもきちんと文字列を扱えるアプリケーションを開発しています、問題となる例です↓
(メッセージボックス)
int MessageBox_OK( HWND hWnd, LPCTSTR lpCaption, LPCTSTR lpText )
{
int ret;
int len_w;
LPWSTR wCaption, wText; //変換後の、UNICODE文字列取得バッファ

//コンパイル設定がUNICODEの時に、ANSIをUNICODEに変換する
#ifdef UNICODE
//ここで文字コードを判定したいです|・ω・`)
//UNICODEでなかったらUNICODEに変換する
len_w = AnsiToUnicode_Size( lpCaption );
len_w = len_w * sizeof(WCHAR);
wCaption = (LPWSTR)malloc( len_w + 1 );
AnsiToUnicode_Convert( lpCaption, wCaption );

//ここで文字コードを判定したいです|・ω・`)
len_w = AnsiToUnicode_Size( lpText );
len_w = len_w * sizeof(WCHAR);
wText = (LPWSTR)malloc( len_w + 1 );
AnsiToUnicode_Convert( lpText, wText );
#else
return MessageBox( hWnd, lpText, lpCaption, MB_OK );
#endif

return MessageBox( hWnd, wText, wCaption, MB_OK );
}

//ANSI→UNICODE (必要サイズ(文字数))
int AnsiToUnicode_Size( LPCSTR strAnsi );

//ANSI→UNICODE (変換)
BOOL AnsiToUnicode_Convert( LPCSTR strAnsi, LPWSTR strUnicode );

よろしくお願いします。

A 回答 (3件)

★IsTextUnicode() 関数を見つけました。


・バッファに Unicode 文字の形式が含まれている可能性が高いかどうか判定します。
 これをそのまま使えば IsUnicode() を自作しなくても良さそうですよ。
 DWORD IsTextUnicode(
  CONST LPVOID lpBuffer, // 調査対象の入力バッファへのポインタ
  int cb, // 入力バッファのサイズ(バイト数)
  LPINT lpi // 実施するテストを指定し、個々のテスト結果を受け取る整数へのポインタ
 );
 と MSDN マニュアルには載っています。
・使い方は下のサンプルのようになります。

サンプル:
BOOL IsUnicode( LPCTSTR str )
{
 INT iRet = IS_TEXT_UNICODE_STATISTICS;
 
 return (BOOL)IsTextUnicode( (LPCVOID)str, lstrlenA((LPCSTR)str), &iRet );
}

その他:
・統計的に調査するようなので確実に Unicode 文字列とは判断されないようです。
 短い文字列では全滅でした。次のリンクにテストしたサンプルが載っています。
 http://www.hey-to.net/ML-archive/vcppML/1999/msg …→『UNICODEテキストとシフトJISテキストの区別』
・SJIS文字、Unicode文字の判定はかなり難しいようです。
 ネットで『IsTextUnicode』キーワードで検索すると多数見つかります。
 全部は見ていないため一度すべてのページに目を通しておきましょう。
・以上。下の『参考URL』もどうぞ。

参考URL:http://msdn.microsoft.com/library/ja/default.asp …
    • good
    • 0

はずしていたらごめんなさい、ですが、



単純にユニコードにしたいだけなら、TCHAR型を使うのではだめですか。

長々とコーディングしなくても、同じ内容が、2~3行ですみませんか。
    • good
    • 0

★アイディア


・文字列の Unicode 文字判定の関数を1つ作って MessageBoxA()、MessageBoxW() 関数を
 使えば良い。そうすれば、AnsiToUnicode_Size()、AnsiToUnicode_Convert() 関数は
 必要なくなります。ただし、lpCaption と lpText の文字列の文字コードが両方とも
 同じ場合に限ります。→擬似サンプル1です。
 もしも、lpCaption と lpText の文字列の文字コードが両方とも違う場合は擬似サンプル2を使う。
・MessageBoxW() 関数で統一すれば #ifdef UNICODE の判定は必要ありませんよ。

擬似サンプル1:
if ( IsUnicode(lpCaption) ){
 MessageBoxW( hWnd, lpText, lpCaption, MB_OK ); ←Ansi,SJIS 版の MessageBox
}
else{
 MessageBoxA( hWnd, lpText, lpCaption, MB_OK ); ←Unicode 版の MessageBox
}

擬似サンプル2:
if ( !IsUnicode(lpCaption) ){
 len_w = AnsiToUnicode_Size( lpCaption );
 len_w *= sizeof(WCHAR);
 wCaption = (LPWSTR)malloc( len_w + 1 );
 AnsiToUnicode_Convert( lpCaption, wCaption );
 lpCaption = (LPCSTR)wCaption;
}
if ( !IsUnicode(lpText) ){
 len_w = AnsiToUnicode_Size( lpText );
 len_w *= sizeof(WCHAR);
 wText = (LPWSTR)malloc( len_w + 1 );
 AnsiToUnicode_Convert( lpText, wText );
 lpText = (LPCSTR)wText;
}
MessageBoxW( hWnd, lpText, lpCaption, MB_OK ); ←Unicode 版の MessageBox で統一する

●肝心の Unicode 文字判定
・文字列が Ansi だと決め付けて強制的に Unicode 文字に変換します。
 その変換された文字列をこんどは強制的に Ansi 文字に変換します。
 その後、最初の文字列と Ansi → Unicode → Ansi の変換した文字列を比較します。
 文字列が完全一致したら本当に Ansi 文字列だった事になります。
 もしも、文字列が不一致なら Unicode 文字の文字列だった事になります。
・こんなアルゴリズムで文字列の Unicode 文字判定の関数が作れませんか。
 もし上手く出来たら上記の擬似サンプル1、または、擬似サンプル2の方法が使えます。
 なお、擬似サンプル2の方法は最終的に Unicode 文字列に合わせて処理するため特に
 #ifdef UNICODE の判定は必要ないと思います。
・以上。参考に!
    • good
    • 0
この回答へのお礼

回答ありがとうございました。参考になりました。Unicode 文字判定を作成してみたのですが。VC2005で「プロジェクトの既定値」→「文字セット」を、設定なしにしてコンパイルして、以下のIsUnicode()にUnicode文字列やANSI文字列を渡して動作させたのですが、うまくいきませんでした。間違いの箇所がどこなのかわかりません。問題ある箇所を教えていただければうれしいです。

BOOL IsUnicode( LPCSTR str )
{
intlen_w, len;
LPWSTRwstrbf;
LPSTRstrbf;

len_w = AnsiToUnicode_Size( str );
len_w *= sizeof(WCHAR);
wstrbf = (LPWSTR)malloc( len_w + 1 );
wmemset( wstrbf, 0, ( len_w + 1 ) );
if ( ! AnsiToUnicode_Convert( str, wstrbf ) ) {
//失敗
}

len = UnicodeToAnsi_Size( wstrbf );
len *= sizeof(CHAR);
strbf = (LPSTR)malloc( len + 1 );
memset( strbf, 0, ( len + 1 ) );
if ( ! UnicodeToAnsi_Convert( wstrbf, strbf ) ) {
//失敗
}

if ( lstrcmpA( str, strbf ) == 0 ) {
return FALSE;
}
return TRUE;
}
よろしくお願いします

お礼日時:2007/05/04 19:41

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています