我是Windows编程的新手,在阅读Petzold的书后,我感到奇怪:
使用TCHAR
类型和_T()
函数声明字符串是否仍然是一种好习惯,或者是否应该在新代码中仅使用wchar_t
andL""
字符串?
我将仅针对Windows 2000及更高版本,并且从一开始我的代码就是i18n。
Answers:
如果我今天在做一个新项目,我仍然会使用TCHAR语法。使用它和WCHAR语法之间并没有太大的实际区别,我更喜欢在字符类型上明确的代码。由于大多数API函数和辅助对象都采用/使用TCHAR类型(例如:CString),因此使用它是很有意义的。另外,如果您决定在某个时候在ASCII应用程序中使用代码,或者Windows是否进化到Unicode32等,它还为您提供了灵活性。
如果您决定采用WCHAR路线,我将对此进行明确说明。也就是说,使用CStringW而不是CString,并在转换为TCHAR时强制转换宏(例如:CW2CT)。
无论如何,这是我的看法。
TCHAR
不应再使用它,但我不同意这是一个坏主意。我还认为,如果选择显式而不是使用TCHAR
,则应该在任何地方都显式。即,也不在声明中使用带有TCHAR
/的函数_TCHAR
(例如_tmain
)。简而言之:保持一致。+1。
TCHAR
最初引入的目的:简化Win 9x和基于Windows NT版本的Windows的代码开发。当时,Windows NT的UTF-16实现是UCS-2,并且字符串解析/操作的算法是相同的。没有代理人。即使使用代理,DBCS(Windows唯一受支持的MBCS编码)和UTF-16的算法也相同:在两种编码中,一个代码点都包含一个或两个代码单元。
我必须同意萨莎。的基本前提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往往是外部表示的首选。
您的应用程序不使用互联网
(现在,这可能是您软件的有效假设,但是...)
网络运行于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
字符类型,以避免平台差异。
#define _UNICODE
甚至到现在,仍有一些应用程序需要维护。传输结束:)
_UNICODE
控制如何在CRT中解析通用文本映射。如果您不想调用Windows API的ANSI版本,则需要定义UNICODE
。
如果您想知道它是否仍在实践中,那么可以-它仍然被大量使用。如果使用TCHAR和_T(“”),没有人会觉得您的代码很有趣。我现在正在处理的项目正在从ANSI转换为unicode-我们正在采用可移植(TCHAR)路线。
然而...
我的投票将是忘记所有ANSI / UNICODE可移植宏(TCHAR,_T(“”)和所有_tXXXXXX调用等),而只是在各处假设使用unicode。如果您永远不需要ANSI版本,我真的看不到可移植的意义。我会直接使用所有宽字符功能和类型。在所有字符串文字前加上L。
在介绍了Windows编程的文章在MSDN上说:
新应用程序应始终调用(API的)Unicode版本。
该TEXT和TCHAR宏是用处不大的今天,因为所有的应用程序应该使用Unicode。
我会坚持wchar_t
和L""
。
我想提出一种不同的方法(两者都不适用)。
总而言之,使用char *和std :: string(假定为UTF-8编码),并且仅在包装API函数时才转换为UTF-16。
可在http://www.utf8everywhere.org中找到有关Windows程序中此方法的更多信息和理由。
TCHAR
/WCHAR
对于某些旧项目可能就足够了。但是对于新应用,我会说“否”。
所有这些TCHAR
/WCHAR
东东都没有因为历史的原因。TCHAR
提供了一种看起来很简洁的方法(伪装),可以在ANSI文本编码(MBCS)和Unicode文本编码(UTF-16)之间进行切换。过去,人们并不了解世界上所有语言的字符数。他们假设2个字节足以表示所有字符,因此使用的固定长度字符编码方案WCHAR
。但是,在1996年Unicode 2.0发布之后,情况就不再如此。
就是说:不管您在CHAR
/ WCHAR
/中使用哪个TCHAR
,程序中的文本处理部分都应该能够处理可变长度的字符以进行国际化。
因此,除了在Windows中从CHAR
/ WCHAR
/中选择一项之外,您实际上还需要做更多的事情TCHAR
:
WCHAR
。由于使用Unicode支持的WinAPI更容易使用这种方式。请访问这个精彩的网站,以进行更深入的阅读:http : //utf8everywhere.org/
是的,一点没错; 至少对于_T宏。不过,我不确定宽字符的内容。
原因是为了更好地支持WinCE或其他非标准Windows平台。如果您100%确定您的代码将保留在NT上,则可以只使用常规的C字符串声明。但是,最好趋向于更灵活的方法,因为与在非Windows平台上#define宏相比,要遍历数千行代码并将其添加到任何地方(如果需要移植某些库)要容易得多到Windows Mobile。
恕我直言,如果您的代码中包含TCHAR,说明您使用的是错误的抽象级别。
在处理文本处理时,请使用对您而言最方便的任何字符串类型-希望这会支持unicode,但这取决于您。根据需要在OS API边界进行转换。
处理文件路径时,请使用自己的自定义类型,而不要使用字符串。这将允许您独立于OS的路径分隔符,与手动的字符串连接和拆分相比,将使您更容易针对代码进行交互的界面,并且将更易于适应不同的OS(ansi,ucs-2,utf-8等)。 。
只是添加一个老问题:
在VS2010中开始一个新的CLR C ++项目。微软自己使用L"Hello World"
。
C
和C++
。答案始终可以由其各自的作者删除。这将是使用该规定的好时机。
TCHAR
具有新的含义端口WCHAR
来CHAR
。
https://docs.microsoft.com/zh-cn/windows/uwp/design/globalizing/use-utf8-code-page
Windows 10的最新版本已使用ANSI代码页和-A API作为向应用程序引入UTF-8支持的一种方式。如果为UTF-8配置了ANSI代码页,则-A API在UTF-8中运行。