Introduction
To write Win32 application or MFC application using C++ you may decide to support Unicode or not. TCHAR library provides us macros so that we can easily switch between those two options.
Tips and Tricks
If you want to use Unicode in project properties if Visual Studio Solution Explorer, you have to select "Use Unicode Character Set" as character set. After that, you can easily use Unicode strings in your code wrapping with a macro. The same macro works fine even if you selected not to use "Unicode Character Set" and you use the character set that ANSI supports for example, english alphabets. Code remains same while you have the advantage.
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
array or 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 2nd parameter 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');
if (base >= 16)
return 0;
if (base == 16) {
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.
History
- 16th January, 2012: Version 4
- 11th May, 2011: Version 3
- 9th May, 2011: Version 2
- 6th May, 2011: Initial version