Перейти к содержимому

Tchar c что это

  • автор:

Использование типов данных tchar.h с _МБ CS

Как указано в таблице сопоставлений подпрограмм универсального текста (см . сопоставления универсального текста), если определена константа _MBCS манифеста, данная подпрограмма универсального текста сопоставляется с одним из следующих типов подпрограмм:

  • Подпрограмма для однобайтовой кодировки, которая правильно обрабатывает многобайтовые символы и строки. В этом случае ожидается, что строковые аргументы будут иметь тип char* . Например, функция _tprintf сопоставляется с функцией printf ; строковые аргументы функции printf имеют тип char* . При использовании универсального строкового типа данных _TCHAR типы формальных и фактических параметров функции printf совпадают, потому что _TCHAR* сопоставляется с char* .
  • Подпрограмма, специально созданная для многобайтовой кодировки. В этом случае ожидается, что строковые аргументы будут иметь тип unsigned char* . Например, функция _tcsrev сопоставляется с функцией _mbsrev , которая ожидает и возвращает строку типа unsigned char* . Опять же, если для строковых типов используется _TCHAR универсальный текстовый тип данных, существует потенциальный конфликт типов, так как _TCHAR сопоставляется с типом char .

Есть три способа предотвратить такой конфликт типов (и избежать предупреждений компилятора C или ошибок компиляции C++).

    Использовать поведение по умолчанию. Файл TCHAR.H содержит прототипы универсальных текстовых подпрограмм, реализованных в библиотеках времени выполнения, как показано в следующем примере.

char *_tcsrev(char *); 
#define _USE_INLINING 

При этом подходе вызывается встроенный преобразователь функции, реализованный в файле TCHAR.H, который непосредственно отображает универсальную текстовую подпрограмму на соответствующую MBCS-подпрограмму. Следующий фрагмент кода из TCHAR. H содержит пример того, как это сделать.

__inline char *_tcsrev(char *_s1)
#define _MB_MAP_DIRECT 

Этот подход обеспечивает быструю альтернативу, если вы не хотите использовать поведение по умолчанию или не можете использовать встраивание. Макрос сопоставляет подпрограмму универсального текста с версией подпрограммы МБ CS, как показано в следующем примере из TCHAR.H.

#define _tcschr _mbschr 

При таком подходе будьте внимательны, чтобы убедиться, что для строковых аргументов и значений возвращаемых строк используются соответствующие типы данных. Можно воспользоваться явным приведением типов, чтобы гарантировать соответствие типов, либо универсальным строковым типом данных _TXCHAR . Тип _TXCHAR сопоставляется с типом char в коде с однобайтовой кодировкой, но в коде с многобайтовой кодировкой он сопоставляется с типом unsigned char . Дополнительные сведения о макросах универсального текста см. в разделе «Сопоставления универсального текста».

Завершение блока, относящегося только к системам Майкрософт

LPSTR, LPWSTR, TCHAR, char*, .

TCHAR — это изобретение Microsoft и куча проблем с ним связано. Если у вас проект на Unicode, то это TCHAR = wchar_t. Если ASCII то TCHAR = char.

#ifdef _UNICODE typedef wchar_t TCHAR; #else typedef char TCHAR; #endif http://www.pvsm.ru/unicode/23896 

Поскольку TCHAR в исходниках примеров драйверов повсюду надо понимать как с ним далее работать. Как следствие надо использовать Windows Safe String Function для разных преобразований:

присвоить значение TCHAR строке :

TCHAR str[100]; StringCchCopy(str, ARRAYSIZE(str), L"127.0.0.1"); /* STRSAFEAPI StringCchCopyA( STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc ); */ 

Если надо int в TCHAR преобразовать (int -> TCHAR):

TCHAR str[100]; StringCchPrintf(str, ARRAYSIZE(str), TEXT("%d"), (int)number); 

присваивание значений строкам

"строка ANSI"; // ANSI L"строка Unicode"; // Unicode TEXT("строка ANSI|Unucode по ситуации как и с TCHAR") _T = TEXT 

LPCSTR понимается так.
• LP — Long Pointer (длинный указатель)
• C – Constant (константа)
• STR – String (строка)
По сути LPCSTR это (Длинный) указатель на строку.

LPSTR общеприменяемый префикс с названии sz

typedef char* LPSTR; 

LPCWSTR,LPWSTR описан так:

typedef const WCHAR* LPCWSTR; typedef WCHAR* LPCWSTR; 

LPCTSTR
LP — Long Pointer (Длинный указатель)
C — Constant (Константа)
T = TCHAR
STR = String (Строка)

Что такое STRSAFE? Смотрим strsafe.h :

typedef __nullterminated char* STRSAFE_LPSTR; typedef __nullterminated const char* STRSAFE_LPCSTR; typedef __nullterminated wchar_t* STRSAFE_LPWSTR; typedef __nullterminated const wchar_t* STRSAFE_LPCWSTR; typedef __nullterminated const wchar_t UNALIGNED* STRSAFE_LPCUWSTR; 

Там же в strsafe.h :

#ifdef UNICODE #define StringCchCopy StringCchCopyW #else #define StringCchCopy StringCchCopyA #endif // !UNICODE #ifdef UNICODE #define StringCchPrintf StringCchPrintfW #else #define StringCchPrintf StringCchPrintfA #endif // !UNICODE 

Скопировать TCHAR* в char* (универсальный вариант)

TCHAR ourIpAdress[100]; char *ipAddres = new char[256]; int cbMultiByte = WideCharToMultiByte(CP_ACP,0,ourIpAdress,sizeof(ourIpAdress),ipAddres,sizeof(ipAddres),NULL,NULL); 

wcstombs(ipAddres, ourIpAdress, sizeof(ourIpAdress)); к сожалению только если UniCode исползуется

TCHAR или собственный макрос?

Недавно глянул в файл tchar.h и увидел объявленный тип TCHAR, который по сути дела делает тоже самое что и этот макрос:

#ifdef UNICODE typedef wchar_t strt; #elif typedef char strt; #endif 

Теперь задаюсь вопросом, стоит ли использовать макрос, или же все таки готовым типом?
Отслеживать
задан 16 окт 2017 в 13:21
user206435 user206435
Я не знаю твоих задач, но лучше вообще не пользуйся таким API. Либо явно wchar_t либо char
16 окт 2017 в 13:38

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

Если Вы работаете под Windows, а судя по упоминанию tchar.h это действительно так. И Ваше приложение должно поддерживать сборку как для широких wchar_t символов, так и для узких char , то использование типа TCHAR , единнственно правильное решение. Другое дело, что в современном мире потребности в этом возникать не должно и поддержка Unicode должна быть доступна номинально.

Что об этом пишет Microsoft:

Back when applications needed to support both Windows NT as well as Windows 95, Windows 98, and Windows Me, it was useful to compile the same code for either ANSI or Unicode strings, depending on the target platform. To this end, the Windows SDK provides macros that map strings to Unicode or ANSI, depending on the platform.

Отслеживать
ответ дан 16 окт 2017 в 14:04
28.8k 12 12 золотых знаков 59 59 серебряных знаков 118 118 бронзовых знаков

Спасибо! Как раз сделал проверку на совместимость типа определенного мной, и TCHAR все корректно работает.

– user206435
16 окт 2017 в 14:13

В 2017 году нет никакого смысла собирать программу без -DUNICODE .
Вместо TCHAR надо использовать wchar_t .

Отслеживать
ответ дан 16 окт 2017 в 14:25
31k 13 13 золотых знаков 96 96 серебряных знаков 157 157 бронзовых знаков
Если не будет потребности в символах юникода, то тогда какой смысл от него?
– user206435
16 окт 2017 в 14:29

Как учит нас Страуструп, лучше пользоваться типом, чем макросом. Потому что макросы это зло типонебезопасное, а тип проверяется компилятором с учетом всех зависимостей для данной платформы. Включая участие в шаблонах и прочие чудеса науки.

не всегда есть возможность к примеру полностью переписывать класс для тестирования поведения в разных кодировках

Это не мое мнение, это я у Страуструпа вычитал (дай ему Бог здоровьичка) еще в одном из первых изданий по С++. Там было написано, что теперь отныне и вовеки макросы нужны только для предотвращения зацикливания хедеров. Что касается тестирования программы с разными типами данных, то нужно использовать typedef для быстрого переопределения типа. Но не макрос. То есть в своей программе пишете:

typedef char my_char;

и работаете с my_char. А когда надо работать с широким байтом, то переопределяете:

typedef wchar_t my_char;

и снова работаете с my_char.

Tchar c что это

Рейтинг (т): 527

tchar не связан непосредственно с переносимостью между исполнительными платформами. Его задача – обеспечить переносимость между ANSI и UNICODE. Самый простой вариант в этом аспекте – просто не использовать юникод как базу. Тем более, что реализаций юникода существует более одной.
Переносимость между исполнительными платформами достигается избавлением от использования любых предположений об их характеристиках. В частности от API операционной системы. Кросс-платформенное ПО использует исключительно стандартные библиотеки, являющиеся частью языка и описываемые Стандартом языка, а также библиотеки третьих сторон, которые тоже кросс-платформенны.

Сообщ. #5 , 16.04.15, 19:05

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

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