如何给TCHAR数组赋值

17

我在我的C++代码中有一个TCHAR数组,我想将静态字符串分配给它。

我通过以下方式设置初始字符串:

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

一切都很好。然而,当我像这样把它分成两行

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

出现编译错误,提示it bug:

错误 C2440: '=': 无法从'const char [14]'转换为'TCHAR [260]'

在这里,TEXT()函数难道不应该做我想要的事情吗?将给定的字符串转换为TCHAR?当将两行代码放在一起时,为什么它能够工作?我需要改变什么才能让它正常运行?

我还遇到了其他令人困惑的事情:

我在互联网上搜索过,发现还有_T()_TEXT()__T()__TEXT()。它们是用来干什么的?在什么环境下应该使用它们中的哪一个?

2个回答

21

分配失败的原因与 TCHAR_T 关系不大。下面的代码也不起作用。

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

原因是在C和C++中,你不能直接赋值数组。相反,你必须逐个复制元素(例如使用strcpy,或在您的情况下使用_tcscpy)。

strcpy(var, "str");

关于你问题的第二部分,TEXT_T和其他宏,在Unicode版本中将字符串字面值转换为宽字符串字面值。在非Unicode版本中,这些宏不起作用。


1
+1 给 avakar。另外,根据您的项目设置(Unicode/ASCII),请使用 TCHAR 而不是 WCHAR 或 char,TCHAR 宏将被定义为 WCHAR/char。同样,请使用基于 _t 的安全函数,如 _tcscpy_s、_tcscat_s 等,这些函数也将根据您的项目设置再次定义为 wcscpy 或 strcpy。这是我的意见。 - legends2k
我尝试了这个,但出现了这个错误:错误 C2664:“wcscpy”:无法将参数 2 从“const char [8]”转换为“const wchar_t *”。 - john k
@user396483,你尝试了什么?显然你把str、_tcs和wcs版本混在一起了。 - avakar

4
请参考avakar的回答来获得直接的答案。我原本想将这句话作为评论添加,但它确实是一个独立的建议。我必须提醒你,这听起来像是一场怒火爆发,但它确实源自于在使用TCHAR并解决了几年问题后企图从相当大的代码库中移除它。

确保您真正理解了使用TCHAR数组及其相关内容带来的影响。它们看似难以正确使用。以下是您必须注意的几个要点:

  • sizeof(TCHAR)是有条件的: 仔细检查包含此代码的代码。如果它正在做除计算传递给malloc()memcpy()的大小之外的任何事情,那么它可能是错误的。
  • TCHAR是类型别名: 因为TCHAR只是一个typedef,所以很容易写出诸如wcscpy(tszStr, wszAry)之类的东西而不知情。基本上,TCHARcharwchar_t,所以重载选择可能会让您感到惊讶。
  • wsprintf()swprintf()是不同的: 这是前面的特殊情况,但它需要特别注意,因为在这里犯错误非常容易!

如果要使用TCHAR,请确保定期编译UNICODEMBCS版本。如果不这样做,那么您可能会撤销您试图通过首次使用它们获得的任何优势。

以下是关于如何在编写C++代码时不使用TCHAR的两个建议:
  1. 如果您正在使用MFC或习惯于与MSFT合作,请使用CString
  2. 在使用特定类型的API时,结合使用std::stringstd::wstring——在适当的情况下使用CreateFileA()CreateFileW()
个人而言,我选择后者,但字符编码和字符串转码问题有时真的很头疼。

+1,我最初也考虑写一个类似的抱怨。个人而言,我总是使用带有UTF-8编码数据的std::string,仅在API边界(即调用win32 API之前)进行重新编码。 - avakar
@avakar:我们已经尝试了UTF-8+std::string和UCS-2+std::wstring两种方法。我更倾向于后者,因为在Unicode中,大小写折叠和比较要容易得多,而不是UTF-8。 - D.Shawley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接