tchar.h での汎用テキスト マッピング
コードを簡単に国際対応にできるように、Microsoft のランタイム ライブラリには、多くのデータ型やルーチンなどのオブジェクトに対して、Microsoft 固有の汎用テキスト マッピングが用意されています。 tchar.h で定義されているこれらのマッピングを使用すると、#define
ステートメントで定義したマニフェスト定数に応じて、1 バイト、マルチバイト、または Unicode の文字セット用にコンパイルできる汎用コードを記述できます。 汎用テキスト マッピングは Microsoft 固有の拡張機能であり、ANSI とは互換性がありません。
tchar.h を使用することで、1 バイト、マルチバイト文字セット (MBCS: Multibyte Character Set)、および Unicode の各アプリケーションを同じソースからビルドできます。 tchar.h では、プレフィックス _tcs
の付いたマクロが定義されていて、正しいプリプロセッサ定義に応じて str
、_mbs
、または wcs
のいずれかの関数にマップされます。 MBCS でビルドするには、シンボル _MBCS
を定義します。 Unicode をビルドするには、シンボル _UNICODE
を定義します。 1 バイト アプリケーションをビルドする場合は、どちらも定義しません (既定)。 MFC アプリケーションでは、既定で _UNICODE
が定義されています。
_TCHAR
データ型は、tchar.h で条件に応じて定義されます。 ビルドでシンボル _UNICODE
が定義されている場合、_TCHAR
は wchar_t
として定義されます。それ以外の 1 バイトと MBCS のビルドでは char
として定義されます。 (Unicode のワイド文字データ型である wchar_t
は、8 ビットの signed char
の 16 ビット版に相当します。)国際対応のアプリケーションには、バイトではなく _TCHAR
単位で動作する _tcs
ファミリの関数を使用してください。 たとえば、_tcsncpy
は、n
バイトではなく n
個の _TCHARs
をコピーします。
1 バイト文字セット (SBCS: Single Byte Character Set) の文字列処理関数の中には、符号付きの char*
パラメーターを受け取るものがあります。このため、_MBCS
を定義すると、型の不一致を知らせるコンパイラの警告が生成される場合があります。 この警告を回避する方法は 3 つあります。
tchar.h でタイプ セーフなインライン関数であるサンクを使用します。 これが既定の動作です。
コマンド ラインで
_MB_MAP_DIRECT
を定義して、 tchar.h で直接マクロを使用します。 この場合は、型を手作業で一致させる必要があります。 これは一番速い方法ですが、タイプ セーフではありません。tchar.h でタイプ セーフな静的リンク ライブラリ関数であるサンクを使用します。 この場合は、コマンド ラインで定数
_NO_INLINING
を定義します。 これは、一番時間がかかりますが、一番タイプ セーフな方法です。
汎用テキスト マッピング用のプリプロセッサ ディレクティブ
#define | コンパイル後の状態 | 例 |
---|---|---|
_UNICODE |
Unicode (ワイド文字) | _tcsrev は _wcsrev にマップされます。 |
_MBCS |
マルチバイト文字 | _tcsrev は _mbsrev にマップされます。 |
なし (既定では _UNICODE も _MBCS も未定義) |
SBCS (ASCII) | _tcsrev は strrev にマップされます。 |
たとえば、tchar.h で定義されている汎用テキスト関数 _tcsrev
は、プログラムで _MBCS
が定義されていると _mbsrev
にマップされ、_UNICODE
が定義されていると _wcsrev
にマップされます。 それ以外の場合、_tcsrev
は strrev
に割り当てられます。 プログラミングに便利なように他のデータ型のマッピングも tchar.h に用意されていますが、_TCHAR
が最も便利です。
汎用テキストのデータ型のマップ
汎用テキスト データ型名 |
_UNICODE & _MBCS が未定義の場合 |
_MBCS 定義済み |
_UNICODE 定義済み |
---|---|---|---|
_TCHAR |
char |
char |
wchar_t |
_TINT |
int |
unsigned int |
wint_t |
_TSCHAR |
signed char |
signed char |
wchar_t |
_TUCHAR |
unsigned char |
unsigned char |
wchar_t |
_TXCHAR |
char |
unsigned char |
wchar_t |
_T または _TEXT |
影響なし (プリプロセッサによって削除される) | 影響なし (プリプロセッサによって削除される) | L (後続の文字または文字列を同等の Unicode に変換する) |
ルーチンや変数などのオブジェクトの汎用テキスト マッピングの一覧については、「ランタイム ライブラリ リファレンス」の「汎用テキスト マッピング」を参照してください。
Note
Unicode の文字列には NULL バイトが含まれている可能性があるため、この文字列と一緒に str
ファミリの関数を使用しないでください。 同様に、MBCS (または SBCS) 文字列には wcs
ファミリの関数を使用しないでください。
MBCS、Unicode、および SBCS の各モデルにマッピングするために、_TCHAR
と _tcsrev
を使用するコード例を次に示します。
_TCHAR *RetVal, *szString;
RetVal = _tcsrev(szString);
_MBCS
が定義されていると、プリプロセッサによって次のコードに変換されます。
char *RetVal, *szString;
RetVal = _mbsrev(szString);
_UNICODE
が定義されていると、プリプロセッサによって次のコードに変換されます。
wchar_t *RetVal, *szString;
RetVal = _wcsrev(szString);
_MBCS
と _UNICODE
のどちらも定義しなかった場合は、プリプロセッサによってこのフラグメントが次のような 1 バイトの ASCII コードにマップされます。
char *RetVal, *szString;
RetVal = strrev(szString);
このように、1 つのソース コード ファイルを記述、保守、およびコンパイルすることで、3 種類のそれぞれの文字セットに固有のルーチンを実行できます。