ICUとは
IBM提供の文字コード変換ライブラリです。
主に、XercesでEUC-JPを正しく使うためににも使えます。
インストール for VC 8(VisualStudio 2005)
IBMのICUのページからICU4Cのicu-x.x.zipをダウンロードします(2006/02/26現在3.4が最新)。
icu-x.x.zipを適当なフォルダに解凍します。解凍して作られたフォルダicuを以後[ICU_FOLDER]と呼びます。
ラ イブラリのビルドは、[ICU_FOLDER]/source/allinone/allinone.slnファイルをVisualStudioで開きま す。このとき、allinone.slnがvc 7.1で作られているため変換しますか?と聞かれるので変換しましょう。
その後、アクティブなターゲットがDebugになっているのを確認して、ソリューションのビルドを行います。次に、アクティブなターゲットをReleaseに変更してソリューションのビルドを行います。
Debug 版→Release版の順でビルドを行うのは、出力されるexeが当たり前ですが、Debug版とRelease版で同名なので、exeについては Release版を残したいためです。ライブラリについては、Debug版はxxxd.dllとdが付いているため区別され、別ファイルとして保存されま す。
ビルドされたライブラリは、[ICU_FOLDER]/libへ出力されます。また、dll、exeは[ICU_FOLDER]/binに出力されます。
使い方
ICUを使うには、
- [ICU_FOLDER]/includeディレクトリをincludeパスに追加
- [ICU_FOLDER]/libの中の必要なライブラリをプロジェクトに追加
- [ICU_FOLDER]/binのdllをPATHの通ったフォルダへコピーなどしてdllをロード出来る状態にする。
sjisをUNICODEへ変換
shift_jisをUNICODEへ変換するには、こんな感じです。windows向けという事で、shift_jisではなく、windows-31jを指定しています。
#include
#include
#include
// ライブラリをリンクするためのおまじない
#ifdef _DEBUG
#pragma comment(lib, "icuucd.lib")
#else
#pragma comment(lib, "icuuc.lib")
#endif
int main(int /* argc */, char** /* argv */)
{
const char* const INPUT_STRING="hogeほげ/~";
UErrorCode error = U_ZERO_ERROR;
// 変換器の初期化
UConverter* cnv = ucnv_open("windows-31j", &error);
if(U_FAILURE(error))
{
// ICUのメモリ解放
u_cleanup();
return 1;
}
// 必要なメモリ量を確認
const int32_t unicodeLen
= ucnv_toUChars(cnv, 0, 0
, INPUT_STRING
, strlen(INPUT_STRING)
, &error);
if(0 == unicodeLen)
{
// 変換器解放
ucnv_close(cnv);
// ICUのメモリ解放
u_cleanup();
return 1;
}
error = U_ZERO_ERROR;
UChar* pBuf = new UChar[unicodeLen+1];
ucnv_toUChars(cnv, &pBuf[0], unicodeLen
, INPUT_STRING
, strlen(INPUT_STRING)
, &error);
if(U_FAILURE(error))
{
delete [] pBuf;
// 変換器解放
ucnv_close(cnv);
// ICUのメモリ解放
u_cleanup();
return 1;
}
pBuf[unicodeLen] = L'\0';
// 変換したUNICODE文字で何か処理をする
// 後始末
delete [] pBuf;
// 変換器解放
ucnv_close(cnv);
// ICUのメモリ解放
u_cleanup();
return 0;
}
UNICODEをsjisへ変換
UNICODEをsjis変換するには、こんな感じです。windows向けという事で、shift_jisではなく、windows-31jを指定しています。
#include
#include
#include
// ライブラリをリンクするためのおまじない
#ifdef _DEBUG
#pragma comment(lib, "icuucd.lib")
#else
#pragma comment(lib, "icuuc.lib")
#endif
int main(int argc, char** argv)
{
const wchar_t* const INPUT_STRING=L"hogeほげ/~";
UErrorCode error = U_ZERO_ERROR;
// 変換器の初期化
UConverter* cnv = ucnv_open("windows-31j", &error);
if(U_FAILURE(error))
{
// ICUのメモリ解放
u_cleanup();
return 1;
}
// 必要なメモリ量を確認
const int32_t mbsLen
= ucnv_fromUChars(cnv, 0, 0
, INPUT_STRING
, wcslen(INPUT_STRING)
, &error);
if(0 == mbsLen)
{
// 変換器解放
ucnv_close(cnv);
// ICUのメモリ解放
u_cleanup();
return 1;
}
error = U_ZERO_ERROR;
char* pBuf = new char[mbsLen+1];
ucnv_fromUChars(cnv, &pBuf[0], mbsLen
, INPUT_STRING
, wcslen(INPUT_STRING)
, &error);
if(U_FAILURE(error))
{
delete [] pBuf;
// 変換器解放
ucnv_close(cnv);
// ICUのメモリ解放
u_cleanup();
return 1;
}
pBuf[mbsLen] = '\0';
// 変換した文字で何か処理をする
// 後始末
delete [] pBuf;
// 変換器解放
ucnv_close(cnv);
// ICUのメモリ解放
u_cleanup();
return 0;
}
マルチバイト・マルチバイト変換(C++らしい解答)
ICUを使って、マルチバイト文字をマルチバイト変換関数を実相してみます。
util.lzhを 見て下さい。そのうち、時間を作って説明を書きます。ひとまず、概要だけ。配列のデータ確保後のメモリ解放忘れを避けるため、boostの scoped_arrayを使っています。また、ucnv_openで確保したデータの解放し忘れを避けるため、UConvCloserというデストラク タでucnv_closeを呼び出すクラスを実相してます。
0 件のコメント:
コメントを投稿