VC++メモ:マルチバイト文字列(char*)とワイド文字列(WCHAR*)の変換

マルチバイト文字列とワイド文字列の相互変換について調べたのでメモします。
あと、文字型はどれを使って良いのかようやくわかってきたのでそれもメモしておきます。
VC++にはいろいろな文字型が存在して混乱したので…;

MFCでCString型を使っている方にはあまり関係ないかもしれないですが…;



[文字型について]

文字型にはchar・WCHAR・TCHARといくつも種類があるので、
最初はどれを使えば良いのかわからず、私はとりあえずUnicodeが使えるWCHAR型を使っていました。
実際に使うならば、マルチバイト文字でもワイド文字でも汎用的に使えるTCHAR型を使ったほうが良いようです。

charマルチバイト文字型
WCHARワイド文字型
TCHAR汎用文字型

ついでに他の文字列型もまとめておきますが、
以下のものはどれも上記の型の文字列を表したものです。

LPSTRchar*
LPCSTRconst char*
LPWSTRWCHAR*
LPCWSTRconst WCHAR*
LPTSTRTCHAR*
LPCTSTRconst TCHAR*




[マルチバイト文字列(char*)とワイド文字列(WCHAR*)の変換]

さて、本題ですが、上述の通り私は最初はWCHAR型をよく利用していました。
WCHAR型を使っていて問題になったのが、他人が作成したdllを使用した場合、
関数の引数の文字型が全てchar型だったことです。

char型とWCHAR型は互換性がないため、そのままでは使用できません。
そのまま渡せばコンパイルエラーですし、強引にキャストしても文字化けが発生してしまいます。

char型とWCHAR型を変換するにはwcstombs_s()やmbstowcs_s()を使います。
これらを使うためにはC言語の標準ライブラリの locale.h をincludeする必要があります。

#include < locale.h >
//ワイド文字列(WCHAR*)をマルチバイト文字列(char*)に変換
errno_t wcstombs_s(
   size_t *pReturnValue,	//変換された文字数
   char *mbstr,		//変換結果のマルチバイト文字列用のバッファのアドレス(変換先)
   size_t sizeInBytes,	//mbstr バッファのサイズ 
   const wchar_t *wcstr,	//変換されるワイド文字列のアドレス(変換元)
   size_t count 		//wcstr に格納するワイド文字の最大数
);
//マルチバイト文字列(char*)をワイド文字列(WCHAR*)に変換
errno_t mbstowcs_s(
   size_t *pReturnValue,	//変換された文字数
   wchar_t *wcstr,		//変換されたワイド文字列を格納するバッファのアドレス(変換先)
   size_t sizeInWords,	//wcstr バッファのサイズ
   const char *mbstr,		//マルチバイト文字列のアドレス(変換元)
   size_t count 		//wcstr に格納するワイド文字の最大数
);
ただし、これらの関数を使用しただけでは正常に変換できない(文字化けする)ことがあります。
この場合はsetlocale()でロケールを指定する必要があります。
ロケールとは「国や地域の文化によって異なる言語や単位、表記などの総称」らしいです。
char *setlocale(
   int category,		//ロケールの影響を受けるカテゴリ
   const char *locale 	//ロケール名
);
正直なところここはよくわかってないんですが、
ソフトで使用する言語を日本語に指定しないと、日本語に変換されないのだと思います。
日本語の場合は、categoryはLC_ALL、localeには"japanese"を指定しておけば大丈夫だと思います。



[サンプルコード]

//ワイド文字列(WCHAR*)をマルチバイト文字列(char*)に変換

//変換前文字列
WCHAR*	wStrW	= _T("ワイド文字列");
//変換文字列格納バッファ
char	wStrC[50];

size_t wLen = 0;
errno_t err = 0;

//ロケール指定
setlocale(LC_ALL,"japanese");
//変換
err = wcstombs_s(&wLen, wStrC, 20, wStrW, _TRUNCATE);
//マルチバイト文字列(char*)をワイド文字列(WCHAR*)に変換

//変換前文字列
char* 	wStrC	= "マルチバイト文字列";
//変換文字列格納バッファ
WCHAR	wStrW[50];

size_t wLen = 0;
errno_t err = 0;

//ロケール指定
setlocale(LC_ALL,"japanese");
//変換
err = mbstowcs_s(&wLen, wStrW, 20, wStrC, _TRUNCATE);


コメント
コメントする








    
この記事のトラックバックURL
トラックバック