Функции printf, wprintf и _tprintf

В языке C/C++ существует два типа символов: обычный char и широкий wchar_t. Для каждого из них предусмотрена своя версия функции форматированного вывода. Для char это printf, а для wchar_twprintf. Но со временем понадобился третий вариант этой функции.

Для упрощения совместимости широких и обычных символов в компании Microsoft ввели третий тип символов, TCHAR. В упрощенном виде он вводится так, как показано ниже (заголовочный файл winnt.h).

typedef char CHAR;
typedef wchar_t WCHAR;

#ifdef UNICODE
   typedef WCHAR TCHAR;
#else
   typedef char TCHAR;
#endif

То есть в зависимости от того, объявлено UNICODE или нет, тип TCHAR раскрывается в обычный символ (char), или в широкий (wchar_t).

Для этих же целей был введен макрос TEXT (и его аналог __T). Они вводятся абсолютно одинаково, но в разных заголовочных файлах: TEXT в winnt.h, а __T в tchar.h.

#ifdef  UNICODE
   #define __TEXT(quote) L##quote
#else
   #define __TEXT(quote) quote
#endif
#define TEXT(quote) __TEXT(quote)

Данный макрос нужен для совместимого объявления строк. Например, следующее объявление является неправильным.

TCHAR s[] = “Hello”;

Почему? В нём строка объявлена в виде последовательности обычных символов. Но тип TCHAR может описывать и широкие символы. Правильное объявление строки выглядит так:

TCHAR s[] = TEXT(“Hello”);

Теперь среда разработки правильно определит тип строки, и ошибки не будет.

Хорошо, но при чем тут printf? Дело в том, что функции printf и wprintf не умеют работать с типом TCHAR. Поэтому для обеспечения совместимости был введен макрос _tprintf. Он вводится в заголовочном файле tchar.h.

#ifdef _UNICODE
   #define _tprintf        wprintf
#else
   #define _tprintf        printf
#endif

Определение _UNICODE вводится так:

#ifdef UNICODE
   #ifndef _UNICODE
      #define _UNICODE
   #endif
#endif

То есть _UNICODE – это полный эквивалент объявления UNICODE, которое определяет тип TCHAR и макрос TEXT.

Обратите внимание, макрос _tprintf просто подменяет название функции. Больше он ничего не делает. Поскольку функции printf и wprintf имеют разный прототип, то для правильной работы вы должны передавать в _tprintf только символы типа TCHAR. Например, так:

TCHAR *str;
//Какой-то код
_tprintf(TEXT(“%s\n”), str);

 

Один ответ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *