【发布时间】:2010-09-19 01:27:49
【问题描述】:
我是 Windows 编程新手,在阅读 Petzold 的书后,我想知道:
使用TCHAR 类型和_T() 函数声明字符串是否仍然是一种好习惯,或者我是否应该在新代码中只使用wchar_t 和L"" 字符串?
我将只针对 Windows 2000 及更高版本,我的代码从一开始就是i18n。
【问题讨论】:
标签: c++ c windows unicode wchar-t
我是 Windows 编程新手,在阅读 Petzold 的书后,我想知道:
使用TCHAR 类型和_T() 函数声明字符串是否仍然是一种好习惯,或者我是否应该在新代码中只使用wchar_t 和L"" 字符串?
我将只针对 Windows 2000 及更高版本,我的代码从一开始就是i18n。
【问题讨论】:
标签: c++ c windows unicode wchar-t
是的,绝对的;至少对于 _T 宏。不过,我不太确定宽字符的东西。
原因是为了更好地支持 WinCE 或其他非标准 Windows 平台。如果您 100% 确定您的代码将保留在 NT 上,那么您可能只使用常规的 C 字符串声明。但是,最好倾向于更灵活的方法,因为在非 Windows 平台上#define 该宏要容易得多,而不是通过数千行代码并将其添加到任何地方,以防您需要移植一些库到 Windows 移动版。
【讨论】:
如果您想知道它是否仍在实践中,那么是的 - 它仍然被大量使用。如果你的代码使用了 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)。
无论如何,这是我的看法。
【讨论】:
简短的回答:否。
就像所有其他人已经写过的一样,很多程序员仍然使用 TCHAR 和相应的函数。在我看来整个概念是个坏主意。 UTF-16 字符串处理与简单的 ASCII/MBCS 字符串处理有很大不同。如果你对它们都使用相同的算法/函数(这是 TCHAR 想法的基础!),如果你做的不仅仅是简单的字符串连接(比如解析等)。主要原因是Surrogates。
唯一的例外是当您真的必须为不支持 Unicode 的系统编译应用程序时,我认为没有理由在新应用程序中使用过去的包袱。
【讨论】:
TCHAR,但我不同意这是一个坏主意。我也认为如果你选择显式而不是使用TCHAR你应该显式无处不在。 IE。也不要在声明中使用带有TCHAR/_TCHAR(例如_tmain)的函数。简单地说:保持一致。 +1,仍然。
TCHARs 最初引入的目的:简化 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 往往更适合用于外部表示。
您的应用程序不使用互联网
(现在,对于你的软件来说,这可能是一个有效的假设,但是...)
The web runs on UTF-8 和 a plethora of rarer encodings。 TCHAR 概念仅识别两个:“ANSI”(can't be 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。始终调用“W”版本的 Windows API 函数。 #define _UNICODE 只是为了确保您不会意外调用“A”函数。
始终对字符串使用 UTF 编码:char 字符串使用 UTF-8,wchar_t 字符串使用 UTF-16(在 Windows 上)或 UTF-32(在类 Unix 系统上)。 typedef UTF16 和 UTF32 字符类型以避免平台差异。
【讨论】:
#define _UNICODE 的情况下仍有应用程序需要维护。传输结束:)
_UNICODE 控制如何在 CRT 中解析通用文本映射。如果不想调用ANSI版本的Windows API,需要定义UNICODE。
只是添加一个旧问题:
在 VS2010 中开始一个新的 CLR C++ 项目。微软自己使用L"Hello World",'nuff 说。
【讨论】:
C 和C++。答案总是可以被各自的作者删除。这将是使用该条款的好时机。
MSDN 上的Introduction to Windows Programming article 说
新应用程序应始终调用 Unicode 版本(API)。
TEXT 和 TCHAR 宏现在用处不大,因为所有应用程序都应该使用 Unicode。
我会坚持使用wchar_t 和L""。
【讨论】:
恕我直言,如果您的代码中有 TCHAR,则说明您在错误的抽象级别上工作。
在处理文本处理时,使用 whatever 字符串类型对您来说是最方便的 - 希望这将是支持 unicode 的东西,但这取决于您。根据需要在 OS API 边界进行转换。
处理文件路径时,请创建自己的自定义类型,而不是使用字符串。这将允许您独立于操作系统的路径分隔符,将为您提供比手动字符串连接和拆分更容易的编码接口,并且更容易适应不同的操作系统(ansi、ucs-2、utf-8 等) .
【讨论】:
我认为使用除显式 WCHAR 之外的任何内容的唯一原因是可移植性和效率。
如果您想让最终的可执行文件尽可能小,请使用 char。
如果您不关心 RAM 的使用并希望国际化像简单的翻译一样简单,请使用 WCHAR。
如果您想让您的代码灵活,请使用 TCHAR。
如果您只打算使用拉丁字符,您不妨使用 ASCII/MBCS 字符串,这样您的用户就不需要那么多 RAM。
对于“从一开始就是 i18n”的人,请节省源代码空间并简单地使用所有 Unicode 函数。
【讨论】:
我想建议一种不同的方法(两者都不是)。
总而言之,使用 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。查看这个精彩的网站以获得更深入的阅读: http://utf8everywhere.org/
【讨论】:
TCHAR 有了新的含义,将WCHAR 移植到CHAR。
https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/use-utf8-code-page
Windows 10 的最新版本使用了 ANSI 代码页和 -A API 作为向应用程序引入 UTF-8 支持的一种方式。如果 ANSI 代码 页面配置为 UTF-8,-A API 以 UTF-8 运行。
【讨论】: