我是Windows编程的新手,在阅读了Petzold的书后,我想知道:
使用TCHAR
类型和_T()
函数来声明字符串或者我是否应该在新代码中使用wchar_t
和L""
字符串仍然是一种好习惯?
我将只针对Windows 2000及以上版本,我的代码将从一开始就是i18n.
简短的回答: 没有.
像所有其他人已经写过的一样,很多程序员仍然使用TCHAR和相应的功能.在我看来,整个概念都是一个坏主意.UTF-16字符串处理与简单的ASCII/MBCS字符串处理有很大不同.如果你对它们使用相同的算法/函数(这就是TCHAR的想法所基于的!),如果你做的不仅仅是简单的字符串连接,你会在UTF-16版本上获得非常糟糕的性能(比如解析等).主要原因是代理人.
唯一的例外是当您真的需要为不支持Unicode的系统编译应用程序时,我认为没有理由在新应用程序中使用过去的这个行李.
我必须同意Sascha.TCHAR
/ _T()
/等的基本前提是你可以编写一个基于"ANSI"的应用程序,然后通过定义宏来神奇地给它支持Unicode.但这是基于几个不好的假设:
您主动构建软件的MBCS和Unicode版本
否则,你会char*
在许多地方滑倒并使用普通的琴弦.
您不在_T("...")文字中使用非ASCII反斜杠转义
除非您的"ANSI"编码恰好是ISO-8859-1,否则结果char*
和wchar_t*
文字将不代表相同的字符.
UTF-16字符串的使用方式与"ANSI"字符串类似
他们不是.Unicode引入了大多数遗留字符编码中不存在的几个概念.代孕.结合人物.正常化.条件和语言敏感的套管规则.
也许最重要的是,UTF-16很少保存在磁盘上或通过Internet发送:UTF-8往往是外部表示的首选.
您的应用程序不使用Internet
(现在,这可能是您软件的有效假设,但......)
网络运行在UTF-8和大量罕见的编码.该TCHAR
概念仅识别两个:"ANSI"(不能是UTF-8)和"Unicode"(UTF-16).它可能有助于使您的Windows API调用支持Unicode,但是对于使您的Web和电子邮件应用程序具有Unicode感知能力是无用的.
您不使用非Microsoft库
没有其他人使用TCHAR
. Poco使用std::string
和UTF-8. SQLite有其API的UTF-8和UTF-16版本,但没有TCHAR
. TCHAR
甚至不在标准库中,所以std::tcout
除非你想自己定义它.
忘记存在"ANSI"编码,除非您需要读取无效的UTF-8文件.别忘TCHAR
了.始终调用Windows API函数的"W"版本. #define _UNICODE
只是为了确保你不小心打电话给"A"功能.
始终对字符串使用UTF编码:UTF-8用于char
字符串,UTF-16(在Windows上)或UTF-32(在类Unix系统上)用于wchar_t
字符串. typedef
UTF16
和UTF32
字符类型,以避免平台差异.
如果你想知道它是否还在实践中,那么是 - 它仍然使用了很多.如果它使用TCHAR和_T(""),没有人会看你的代码有趣.我正在研究的项目是从ANSI转换为unicode - 我们将采用便携式(TCHAR)路由.
然而...
我的投票将是忘记所有ANSI/UNICODE可移植宏(TCHAR,_T("")和所有_tXXXXXX调用等...)并且只是假设unicode到处都是.如果你永远不需要ANSI版本,我真的没有看到便携的重点.我会直接使用所有宽字符函数和类型.使用L预先添加所有字符串文字.
如果我今天正在做一个新项目,我仍然会使用TCHAR语法.使用它和WCHAR语法之间没有太大的实际区别,我更喜欢在字符类型中明确的代码.由于大多数API函数和辅助对象采用/使用TCHAR类型(例如:CString),因此使用它是有意义的.此外,如果您决定在某个时刻使用ASCII应用程序中的代码,或者Windows曾经演变为Unicode32等,它会为您提供灵活性.
如果您决定采用WCHAR路线,我会明确表示.也就是说,使用CStringW而不是CString,并在转换为TCHAR时转换宏(例如:CW2CT).
无论如何,这是我的意见.
在介绍了Windows编程的文章在MSDN上说:
新应用程序应始终调用(API的)Unicode版本.
该TEXT和TCHAR宏是用处不大的今天,因为所有的应用程序应该使用Unicode.
我会坚持wchar_t
和L""
.
我想建议一种不同的方法(两者都不是).
总而言之,使用char*和std :: string,假设使用UTF-8编码,并且只在包装API函数时才转换为UTF-16.
有关Windows程序中此方法的更多信息和理由,请访问http://www.utf8everywhere.org.
TCHAR
/ WCHAR
对于一些遗留项目来说可能就够了.但是对于新的应用程序,我会说NO.
由于历史原因,所有这些TCHAR
/ WCHAR
东西都在那里.TCHAR
提供了一种看似简洁的方式(伪装)来在ANSI文本编码(MBCS)和Unicode文本编码(UTF-16)之间切换.过去,人们并不了解世界上所有语言的字符数.他们假设2个字节足以表示所有字符,因此具有固定长度的字符编码方案WCHAR
.但是,在1996年发布Unicode 2.0之后,这已不再适用.
也就是说:无论你在CHAR
/ WCHAR
/中使用哪个TCHAR
,程序中的文本处理部分都应该能够处理可变长度的字符以进行国际化.
所以,你真正需要做的不是选择一条由多CHAR
/ WCHAR
/ TCHAR
在Windows编程:
如果您的应用程序很小并且不涉及文本处理(即只是将文本字符串作为参数传递),那么请坚持使用WCHAR
.由于这种方式更容易使用支持Unicode的WinAPI.
否则,我建议使用UTF-8作为内部编码并将文本存储在char字符串或std :: string中.在调用WinAPI时将它们转换为UTF-16.UTF-8现在是主要的编码,并且有许多方便的库和工具来处理UTF-8字符串.
查看这个精彩的网站,以获得更深入的阅读:http: //utf8everywhere.org/