tags:

views:

1132

answers:

2

I have a TCHAR array in my C++ code which I want to assign static strings to it.

I set an initial string to it via

TCHAR myVariable[260] = TEXT("initial value");

Everything works fine on this. However, when I split it in two lines as in

TCHAR myVariable[260];
myVariable = TEXT("initial value");

it bugs and gives a compiler error:

error C2440: '=': cannot convert from 'const char [14]' to 'TCHAR [260]'

shouldn't the TEXT() function do exactly what I want here? convert the given string to TCHARs? Why does it work, when putting the two lines together? What do I have to change in order to get it working?

Some other confusing thing I have encountered:

I've searched the internet for it and have seen that there are also _T() and _TEXT() and __T() and __TEXT(). What are they for? Which of them should I use in what environment?

+8  A: 

The reason the assignment doesn't work has very little to do with TCHARs and _T. The following won't work either.

char var[260];
var = "str";   // fails

The reason is that in C and C++ you can't assign arrays directly. Instead, you have to copy the elements one by one (using, for example, strcpy, or in your case _tcscpy).

strcpy(var, "str");

Regarding the second part of your question, TEXT, _T and the others are macros, that in Unicode builds turn a string literal to a wide-string literal. In non-Unicode builds they do nothing.

avakar
+1 to avakar. On a side note, use TCHAR instead of WCHAR or char, depending on your project settings (Unicode/ASCII) the TCHAR macro will be defined as WCHAR/char. And likewise use _t based secure functions like _tcscpy_s, _tcscat_s, etc. which will be defined again based on your proj. settings as wcscpy or strcpy.My 2 cents.
legends2k
+4  A: 

See avakar's answer for the direct answer. I was going to add this as a comment, but it really is a freestanding recommendation. I will warn you up from that this will sound like a rant but it does come from using TCHAR and then working issues for a few years before trying to remove it from a rather large codebase.

Make sure that you really understand the effect of using TCHAR arrays and their friends. They are deceptively difficult to use correctly. Here is a short list of things that you have to watch out for:

  • sizeof(TCHAR) is conditional: Scrutinize code that contains this. If it is doing anything other than calculating the size that is being passed to malloc() or memcpy() then it is probably wrong.
  • TCHAR is a type alias: Since TCHAR is nothing more than a typedef, it is really easy to write things like wcscpy(tszStr, wszAry) and be none the wiser. Basically, TCHAR is either char or wchar_t so overload selections might surprise you.
  • wsprintf() and swprintf() are different: This is a special case of the previous but it bears special consideration since it is so easy to make a mistake here!

If you want to use TCHAR, then make sure that you compile both UNICODE and MBCS versions regularly. If you do not do this, then you are probably going to undo any advantage that you are trying to gain by using them in the first place.

Here are two recommendations that I have for how to not use TCHAR in the first place when you are writing C++ code.

  1. Use CString if you are using MFC or are comfortable tying yourself to MSFT.
  2. Use std::string or std::wstring in conjunction with the type-specific API - use CreateFileA() and CreateFileW() where appropriate.

Personally, I choose the latter but the character encoding and string transcoding issues are just a nightmare from time to time.

D.Shawley
+1, I originally considered writing a similar rant. Personally, I always use `std::string` with utf-8 encoded data, recoding only at the API boundaries (i.e. before calls to win32 API).
avakar
@avakar: we've done both the UTF-8+std::string and UCS-2+std::wstring approach. I've taken to the later since case folding and comparisons are much easier in Unicode than UTF-8.
D.Shawley