TCHAR in VC++
/* String functions */ _tcscpy_s, _tcscat_s, _tcslen, _tcsnlen, _tcschr, _tcsdup, _tprintf, _tprintf_s, _stprintf, _stprintf_s /* String conversion functions */ // Convert string to number _tstoi, _tstof, _tstol, _tcstod, _tcstol, _tcstoul _ttoi, _ttol, _ttoi64 // Convert number to string _itot_s, _ltot_s, _ultot_s, _i64tot_s, _ui64tot_s
To use a Unicode string
as a function parameter, wrap it with macro _T
or TEXT
macro. For example:
AfxMessageBox(_T("You clicked it!"));
_T()
and TEXT()
are macros from tchar
header file. TCHAR
library automatically maps functions to Unicode when Unicode is defined. Using TCHAR
library helps us to move code to multibyte stream (or unicode) whenever required. Try to avoid primitive data type char
char *
. This is because before using them in your controls, you have to convert them. Repetitive conversion may be tedious.
Use TCHAR
instead of char
and use TCHAR*
instead of char*
. TCHAR*
can be written LPTSTR
. For const TCHAR*
, you may write LPCTSTR
which is required when a string
is passed as an argument to a function where modification should be restricted.
To calculate length of string
s, use _tcslen
function:
len = _tcslen(str);
To compare string
s instead of strcmp
and strncmp
, use _tcscmp
and _tcsncmp
. Here’s an example:
if (!_tcsncmp(line, _T("desiredtext"), 11))
AfxMessageBox(_T("Got desired text."));
For copying string _tcscpy_s
and _tcsncpy_s
instead of strcpy
and strncpy
:
_tcsncpy_s(dest, srcstr, 20);
Note, strpy
or _tcscpy_s
, don’t put a null
after copying the string
so remember to set null
after copying the string
when required.
For string
concatenation, use _tcscat_s
and _tcsncat_s
instead of strcat
and strncat
. Here, the 2ndparameter is the size of the destination string
.
_tcsncat_s(timestamp, 20, str, i);
For splitting tokens, use _tcstok_s
instead of strtok
.
LPTSTR next_token;
token = _tcstok_s(str, delim, &next_token);
To convert a string
to integer, you can use _ttoi()
function.
CString str = _T("10");
CString temp;
temp.Format(_T(" length: %d"), _ttoi(str));
AfxMessageBox(str+temp);
When I didn't know about this handy function I wrote the following function to do the same task. Having a look at the function may help you as an example code:
int GetEquivValue(TCHAR ch, int base) {
int diff = _T('a') - _T('A');
// Invalid base
if (base >= 16)
return 0;
if (base == 16) {
// make upper case if lowercase
if (ch >= _T('a') && ch <= _T('z'))
ch -= diff;
diff = _T('A') - _T('0');
if (ch >= _T('A') && ch <= _T('F'))
return (ch-diff);
}
if (ch >= _T('0') && ch <= _T('9'))
return (ch - _T('0'));
return 0;
}
int SAatoib(LPTSTR str, int base) {
int res = 0;
int i, len, tmp;
len = _tcslen(str);
for (i=0; i<len; i++) {
tmp = GetEquivValue(str[i], base);
res = res*base + tmp;
}
return res;
}
Using these functions to convert a string
to decimal number, you have to write like this:
int decVal = SAatoib((LPTSTR )NumStr, 10);
To convert a string
to hexadecimal number, you have to write like this:
int decVal = SAatoib((LPTSTR )NumStr, 16);
To convert a string
to octal number, you have to write:
int decVal = SAatoib((LPTSTR )NumStr, 8);
To format the string
like printf
, you can use CString::Format
function. For example, to get IP address:
unsigned long int ipsegval[4] = {1, 2, 3, 4};
CString ip;
ip.Format(_T("%u.%u.%u.%u"), ipsegval[0], ipsegval[1], ipsegval[2], ipsegval[3]);
For example, you have a CString
. But you need it as const char*
or char*
The cast to LPCTSTR
from CString
is a valid one, but cast to const char*
isn’t valid. But there is a way. Here’s an example:
CString ipaddrstr(_T("1.2.3.4"));
CStringA ipaddrstrA(ipaddrstr);
ipaddr = inet_addr(ipaddrstrA);
Note: inet_addr
function requires char *
.
I hope this post helps beginners.