The help you needed in C, C++, MFC
Complete tutorials with free source code
PDF Print E-mail

Windows string types

Now, let us see what are the string types we use in windows. Windows provides large number of API functions for programs running on windows.

For an example, let us take the API function DeleteFile which we use to delete a file. Actually there are 2 DeleteFile functions provided by windows, DeleteFileA and DeleteFileW. The difference between these functions is that the first one accepts ASCII string as argument (the path of the file to delete) and the second one accepts UNICODE string as argument. Without knowing it, we just use DeleteFile to delete a file. How are we able to do it like that?

When we are using a wizard to build an application in Visual Studio, the wizard asks us whether we need to use UNICODE libraries or ASCII libraries. If we selected UNICODE, the class wizard adds a command line argument to the compiler which is similar to the following line added to one of the header files it includes for our project. You may not be that familiar with preprocessor directives, but the directives used in these examples are so easy to understand.

#define UNICODE

The above statement defines a constant UNICODE. Now let us see how DeleteFile is defined. It is defined in WinBase.h, which is included automatically through the header stdafx.h which the wizard includes for our project.

#ifdef UNICODE
#define DeleteFile DeleteFileW
#else
#define
DeleteFile DeleteFileA
#endif

This code specifies to the preprocessor if UNICODE is defined somewhere above, replace DeleteFile with DeleteFileW, or if UNICODE is not defined, replace it with DeleteFileA. So, if we chose to use UNICODE, because the wizard defines UNCODE, we automatically use the correct function DeleteFileW.

Now, think what will happen if we chose to use to use UNICODE functions, but we send ASCII strings to those functions as arguments. Simply, the code will not compile, but one can use a cast and make it compile. But certainly, because of the different encoding, the function will not get what we needed to send it. Note that some people do not even know that this kind of a scenario exists. So, how this problem has overcome?

In windows, another string type TCHAR is introduced to solve this problem. TCHAR is not a separate character type. Inspect the following definition of TCHAR.

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

Here, if we have defined UNICODE, TCHAR will be simply wchar_t and if we do not have defined UNICODE, TCHAR will be char. So, we can send a TCHAR string to API functions such as our previous example DeleteFile without a fear that we are sending the incorrect string type.

If we have defined UNICODE, DeleteFile is actually DeleteFileW, and TCHAR is wchar_t. So sending TCHAR string will cause no problem. If we have not defined UNICODE, then DeleteFile is actually DeleteFileA, and TCHAR is char. Then also, sending a TCHAR string will not cause a problem.

Next problem is, how to initialize a TCHAR string. We use the macro TEXT to initialize a TCHAR string. The macro TEXT is defined as something like this.

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

In the above definition of TEXT, if UNICODE is defined, TEXT is equal to prefixing L to the quote, making the string a unicode string. if UNICODE is not defined, the macro TEXT will not do anything.

Take the following line of code.

TCHAR *string = TEXT("this is a string");

If UNICODE is defined, after preprocessing the above line becomes,

wchar_t *string = L"this is a string";

If UNICODE is not defined, after preprocessing, the same line will become,

char *string = "this is a string";

So, as you can see, the appropriate types are selected automatically by the preprocessor due to the definitions of TCHAR and TEXT. If you find it difficult to type TEXT, you can use _T instead. Both TEXT and _T are equivalent.

You do not need to declare a string variable separately to send as an argument to an API function. You can simply do like this.

DeleteFile(TEXT("C:\\abc.txt"));

 

In Win32 functions, various string types are expected as arguments. Here is a list of the string types used in those functions and the meaning of those types when you use UNICODE and when you are not using UNICODE.

String Type
Meaning When UNICODE is used
Meaning when UNICODE is not used
WCHAR wchar_t wchar_t (same as when UNICODE is used)
LPSTR Null terminated string of characters
(char *)
Same as when UNICODE is used
LPCSTR Constant LPCTSTR
(const char *)
Same as when UNICODE is used
LPWSTR Null terminated string of unicode characters
(wchar_t *)
Same as when UNICODE is used
LPCWSTR Constant LPWSTR
(const wchar_t *)
Same as when UNICODE is used
TCHAR char wchar_t
LPTSTR Null terminated string of TCHAR
(equivalent to char *)
Equivalent to wchar_t *
LPCTSTR Constant LPTSTR
(equivalent to const char *)
Constant LPTSTR
(equivalent to const wchar_t *)