• 締切済み

■文字コード判定■

あるバッファに入っている文字列の文字コード(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 ); よろしくお願いします。

みんなの回答

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.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/msg04973.html→『UNICODEテキストとシフトJISテキストの区別』 ・SJIS文字、Unicode文字の判定はかなり難しいようです。  ネットで『IsTextUnicode』キーワードで検索すると多数見つかります。  全部は見ていないため一度すべてのページに目を通しておきましょう。 ・以上。下の『参考URL』もどうぞ。

参考URL:
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpintl/html/_win32_istextunicode.asp
全文を見る
すると、全ての回答が全文表示されます。
回答No.2

はずしていたらごめんなさい、ですが、 単純にユニコードにしたいだけなら、TCHAR型を使うのではだめですか。 長々とコーディングしなくても、同じ内容が、2~3行ですみませんか。

全文を見る
すると、全ての回答が全文表示されます。
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.1

★アイディア ・文字列の 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 の判定は必要ないと思います。 ・以上。参考に!

Daisuke-now
質問者

お礼

回答ありがとうございました。参考になりました。Unicode 文字判定を作成してみたのですが。VC2005で「プロジェクトの既定値」→「文字セット」を、設定なしにしてコンパイルして、以下のIsUnicode()にUnicode文字列やANSI文字列を渡して動作させたのですが、うまくいきませんでした。間違いの箇所がどこなのかわかりません。問題ある箇所を教えていただければうれしいです。 BOOL IsUnicode( LPCSTR str ) { int len_w, len; LPWSTR wstrbf; LPSTR strbf; 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; } よろしくお願いします

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ワイド文字列とコンストラクタ

    ワイド文字列(UNICODE)をクラス化しようとしているのですが、 コンストラクタにconst wchar_t*型の引数を持たせて呼び出すと、 コンストラクタに渡された文字列が消えてしまい、wcslen()でサイズを求めると何故かサイズも0になっています。 class WideString { public: WideString(const wchar_t*); … }; WideString::WideString(const wchar_t* ws) { ::OutputDebugString(ws); // ←文字列が消えてる?表示されない int len = wcslen(ws); // ←これが0 } int main(void) { WideString wStr(L"文字列"); … } これは一体どういうことなのでしょうか。どなたか教えてください。

  • _tcscat がうまくいきません(VC++2008)

    以下のように入力し、ビルドすると 「error C2664: 'wcscat' : 1 番目の引数を 'LPCTSTR' から 'wchar_t *' に変換できません。」となり、うまくいきません。 ダイアログに「テストです。」と表示させたいです。一体どうしたらよいのでしょうか?ご教授ください~。 環境は、WindowsXP SP2 & Visual C++ 2008 Express Edition です。 なお、文字セットは「Unicode 文字セットを使用する」に設定してあります。 //----------------------------------------------------------- #include <Windows.h> #include <tchar.h> INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE,LPSTR,INT){ LPCTSTR str1 = _T("テスト"); LPCTSTR str2 = _T("です。"); _tcscat( str1, str2 ); MessageBox(NULL,str1,_T("Dialog"),MB_OK); return 0; }

  • 「C#」文字コードの取得&文字変換

    C#で文字コードを調べるプログラムを作成しています。 そこで2つ質問をさせてください。 1つ目(文字コード調べ) TextBoxに漢字を入力して,各エンコーディングの文字コードを調べるときに,UNICDEの場合, Encoding enc_default = Encoding.GetEncoding(932); string input = tb_input.Text; byte[] byte_input = enc_default.GetBytes(input); string outtext_unicode = ""; Encoding enc_unicode = Encoding.Unicode; byte[] byte_unicode = Encoding.Convert(enc_default,enc_unicode, byte_input); foreach (byte b in byte_unicode) { outtext_unicode += string.Format("{0:X}", (int)b); } tb_output_unicode.Text = outtext_unicode; とすると,調べたい文字コードがLE(リトルエディアン)で出力されます。これをBE(ビッグエディアン)で出力されるにはどうしたらよいでしょうか? ご存知の方がいらっしゃいましたら,ぜひ教えてください。 よろしくお願いいたします。 2つ目(文字コードから文字を取得する) 上記の質問と逆のパターンで,TextBoxに文字コードを入力してもらい,人間が読める文字に変換する場合下記のようなコードを書くと, string codePoint_string = tb_output_unicode.Text; int codePoint = int.Parse(codePoint_string); char c = (char)codePoint; tb_input.Text = Convert.ToString(c); ASCIIの文字コードを入力した場合には,きちんと変換してくれるのですが,漢字の文字コードを入力すると,FormatExceptionが発生します。 何か勘違いをしているのかもしれませんが,いまいちやり方が創造できません。 こちらも,ご存知の方がいらっしゃいましたら,ご教示願います。

  • VC++2008でのサンプルプログラムのビルド

    VC++2008を使用してWin32APIを使ったプログラムを動かしたいと思っている者です。 これまでC言語については多少学んできましたがC++を使用するのは初めてです。 まずはサンプルプログラムを動かそうと思い以下のソースを入力しました。 #include <windows.h> #include <tchar.h> int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int showCmd) { MessageBox( NULL, _T("Hello World"), _T("メッセージ"), MB_OK ); return 0; } そしてこれをビルドしてみたところエラーメッセージがでてしまいうまくビルドできませんでした。 参考にしているHPはVC++2008での作業を推奨していたので、動作環境の違いなどではないと思うのですが… 初期設定等の問題になるのでしょうか?解決策があれば教えていただきたいです。 以下が表示されるエラーメッセージです。 1>1.obj : error LNK2028: 未解決のトークン (0A000044) "extern "C" int __stdcall MessageBoxW(struct HWND__ *,wchar_t const *,wchar_t const *,unsigned int)" (?MessageBoxW@@$$J216YGHPAUHWND__@@PB_W1I@Z) が関数 "extern "C" int __cdecl MessageBox(struct HWND__ *,wchar_t const *,wchar_t const *,unsigned int)" (?MessageBox@@$$J0YAHPAUHWND__@@PB_W1I@Z) で参照されました。 1>1.obj : error LNK2019: 未解決の外部シンボル "extern "C" int __stdcall MessageBoxW(struct HWND__ *,wchar_t const *,wchar_t const *,unsigned int)" (?MessageBoxW@@$$J216YGHPAUHWND__@@PB_W1I@Z) が関数 "extern "C" int __cdecl MessageBox(struct HWND__ *,wchar_t const *,wchar_t const *,unsigned int)" (?MessageBox@@$$J0YAHPAUHWND__@@PB_W1I@Z) で参照されました。 1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\1\Debug\1.exe : fatal error LNK1120: 外部参照 2 が未解決です。

  • 関数のコピー

    以下のようなソースがあります。 していることは、char配列に関数をコピーしています。それを関数ポインタに変換して、実行しています。 自作の場合はできるのですが、 MessageBoxをコピーすると以下(字数の関係上無理でした。)のようにメモリ内容がなっており、そのままコピーしたつもりですが、若干異なっております。 どのようにすればMessageBoxがじっこうできるのか, 教えていただきたく質問しました。 よろしくお願いします。 mb,code3が該当分です。 //ソース #include<stdio.h> #include<memory.h> #include<windows.h> int func(int cnt) { return cnt*10; } int func2(int cnt,int cnt2) { return cnt+cnt2; } char *func3() { return "Hello"; } int main() { int (*fa)(int); //MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaotion,UINT uType); int (*fm)(int,int); int (*mb)(HWND,LPCTSTR,LPCTSTR,UINT); char *(*hl)(void); /*fa=func; printf("%d",fa(5)); getchar(); */ char code[12800]; char code2[12800]; char code3[80000]; char code4[12800]; memset(code,0,12800); memset(code2,0,12800); memset(code3,0,80000); memset(code4,0,12800); memcpy(code,(char *)func,12800); memcpy(code2,(char *)func2,12800); memcpy(code3,(char *)MessageBox,80000); memcpy(code4,(char *)func3,12800); fa=(int(*)(int))(void *)code; fm=(int(*)(int,int))(void *)code2; mb=(int(*)(HWND,LPCTSTR,LPCTSTR,UINT))(void *)code3; hl=(char *(*)(void))(void *)code4; printf("%d\n",fa(3)); printf("%d\n",fm(3000,10)); printf(hl()); MessageBox(NULL,"","",MB_OK); mb(NULL,"","",MB_OK); getchar(); return 0; }

  • UTF8→ShiftJISに変換したいです!

    VC++2010, MFCです。 参考ページ(↓)でできそうだったのですが、 http://www.sutosoft.com/oldroom/devdiary/20020504.html UTF-8からShift_JISにしたいのは、メディアプレーヤーで作られた wpl ファイルも扱いたいからです。 具体的にいうと、ファイル一覧に プレイリストがあった場合、展開してメディアプレイヤーで開いて、再生後 【m3u ファイル】に(コーディングで)アウトプットするのが目的です。 ShiftJISに変換して、いったんファイルに出力してから、再度読込処理を行ってもかまいません。 BOOL C○○Dlg::UTF8ToShiftJIS(const CString& src, CString* dest) {  int sizeOfString = (src.GetLength() + 1);  LPWSTR lpsz = new WCHAR[sizeOfString];  //LPSTR lpsz = new char[ sizeOfString ];  _tcscpy_s(lpsz, sizeOfString, src);    //strcpy_s(lpsz,sizeOfString, src);  //delete[] lpsz //http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200612/06120010.txt //char* orig = "Hello, World"; char* nstring; nstring = new char[sizeOfString]; strcpy_s(nstring,sizeOfString, (LPCSTR)(lpsz)); // ●UTF8からUnicodeに変換した場合の長さを求める。●  //http://msdn.microsoft.com/ja-jp/library/cc448053.aspx  //const_cast<LPTSTR>(static_cast<LPCTSTR>(str)  int iWideLength = ::MultiByteToWideChar(CP_UTF8, 0,【1】nstring, src.GetLength(), NULL, 0);  if (iWideLength == 0)return FALSE;  LPWSTR lpWideString = new WCHAR[iWideLength];  int iLength;  if (    // ●UTF8からUnicodeに変換する。●    (::MultiByteToWideChar(CP_UTF8, 0, 【2】nstring, src.GetLength(), lpWideString, iWideLength) == 0)    // ●UnicodeからShift_JISに変換した場合の長さを求める。●    || ((iLength = ::WideCharToMultiByte(CP_ACP, 0, lpWideString, iWideLength, NULL, 0, NULL, NULL)) == 0)    // ●UnicodeからShift_JISに変換する。●        //http://msdn.microsoft.com/ja-jp/library/cc448089.aspx    || (::WideCharToMultiByte(CP_ACP, 0, lpWideString, iWideLength, 【3】(LPSTR)dest->GetBuffer(iLength), iLength, NULL, NULL) == 0)){    // ●変換に失敗●    delete lpWideString;    return FALSE;  }  // ●変換に成功●  delete lpWideString;  dest->ReleaseBuffer();  return TRUE; } ・・・という風に少し修正をして、次のソースで呼び出しています。  CString src;  CFile file;  if (file.Open(FilePath, CFile::modeRead)){   DWORD iLength = file.GetLength();   //CString src;   file.Read(src.GetBuffer(iLength), iLength);   file.Close();   src.ReleaseBuffer(iLength);   CString dest;   if (UTF8ToShiftJIS(src, &dest) ==TRUE){    MessageBox (dest);   }   // ●この時点で、destにShift_JISに変換された文字列が格納されている。  } 以下(↓)を参考に、【1】~【3】の部分で、他のパターンもキャストしてみたのですが・・・ /* http://d.hatena.ne.jp/shikaku/20090519/p3 ■[CPP][VC]LPCSTRなどのVC++の紛らわしい定義の意味 一見正体不明のVC++オリジナル定義。よーくみれば違いが分かる。名前 意味 LP *(ポインタ) C const TSTR TCHAR(char) STR char WSTR WCHAR(ユニコード用:2byte) ゆえに定義 正体 LPSTR char* LPCSTR const char* LPTSTR TCHAR* LPCTSTR const TCHAR* LPWSTR WCHAR* LPCWSTR const WCHAR* となる。+/ できるだけスマートに記述したいです。エクセル版を作っていたときは、CreateObject("ADODB.Stream")を使っていたみたいです。ただ、VC++でどう書けばいいか、分かりませんυ UTF8→UTF16→ShiftJIS ←これは、あまり、使いたくない 変換 です。 後は、これも参考になりそうですが、 http://www.softist.com/programming/sjis-utf8/sjis-utf8.htm bufUTF8を何型でどこで宣言すればいいのか?分かりません。 これも(↓)はてなです。 http://www.s-cradle.com/developer/sophiaframework/sf_reference/ref.SFXTextEncoding.html 何回も試しましたが、TRUEが返ってきても、変換前と変換後をMessageBoxで比べてみても、変わりがなく、漢字や記号の羅列でしかありません。どうか教えてください。

  • DLL呼出し元の使用コード判定法???

    .NET C++でDLL(マルチバイト指定)を作りました DLL呼出し元からデータを受取り別の表示プログラム(マルチバイト指定)に渡して表示させます DLL呼出し元がマルチバイト指定である時には正確に表示します ところがDLL呼出し元がUNICODE指定である場合にはメチャクチャな文字が表示されます 多分UNICODEの際にはDLL内部でANSIに変換してから表示プログラムに渡せば良いのだろうと思います ところがDLL呼出し元がANSI/UNICODEのいづれかを使用しているかの判定方法が分かりません この辺りのことをご指導お願い申し上げます

  • 文字化けを直したい

    visual stadio C++ で、テキストファイルを読み込み、それをウインドウに表示するというプログラムを作っているのですが、表示すると文字化けしてしまいます。 原因がわかりません。 教えてください。 VC++ 2010です。 サイトを見て設定でマルチバイトに変えてあります case IDB_SELECT:{ HDC hDC; errno_t error; static LPCTSTR TEST_STR ;//= _T("左ボタンが押されました"); // ファイルを開くコモンダイアログを作成 if( !GetOpenFileName( &ofn ) ){ MessageBox( hWnd, _T("エラー"), _T("エラー"), MB_OK ); SendMessage( hWnd, WM_CLOSE, 0, 0 ); return 0; } // 選択されたファイル名を表示 MessageBox( hWnd, filename_full, _T("OK"), MB_OK ); int k=0; fp = fopen( "test.txt", "r" ); if( fp == NULL ) /* 関数が失敗していないか */ { MessageBox( hWnd,"読み込み失敗", _T("bad"), MB_OK ); return 1; /* 異常終了は0以外を返す */ } MessageBox( hWnd,"読み込み成功", _T("good"), MB_OK ); hDC = GetDC( hWnd ); while (fgets(file, 80, fp) != NULL){ TEST_STR = &file[k]; TextOut( hDC, 50, k*15+50, TEST_STR, (int)_tcslen(TEST_STR) ); k++; } fclose(fp); } return 0L; } InvalidateRect(hWnd, NULL, TRUE); // 再描画命令発 return 0L;

  • ワイド文字についてのURLをPlzです

    ワイド文字やUnicodeの文字について詳しいサイトあったら教えてください。 レベル的には #include <stdio.h> #include <wchar.h> int main(){ wchar_t *wc = L"wchar_tワイド文字列でえす。"; fputws(wc, stdout); return 0; } これを実行して、なんで日本語が表示されないのかがさっぱりわからないレベルです。。 お願いします。 (注:教えていただきたいのは、上のプログラムの間違っている箇所でなく、それがわかるようになるようなサイトです。)

  • MySQL文字コード

    DB情報をHTMLで表示する場合に、mb_convert_encoding()で指定する文字コード MySQL5.1 PHP5 HTML - shift_jis MySQL の文字セット UTF-8 Unicode (utf8) MySQL の接続照合順序: ujis_japanese_ci フィールドの照合順序 ujis_japanese_ci PHPプログラムでDB情報取得後にSJISに変換 mb_convert_encoding($String, "SJIS", "●●●"); ●●●の文字コードを何を指定すればいいのかがわかりません。 EUCを書くとうまくいってるような気もしますが、なぜEUCでうまくいく のかもわかりません。 ご教授下さい。

    • 締切済み
    • PHP