88

我是 Windows 编程的新手,在阅读 Petzold 的书后,我想知道:

TCHAR使用类型和_T()函数来声明字符串是否仍然是一种好习惯,或者我是否应该只在新代码中使用wchar_t和字符串?L""

我将只针对 Windows 2000 及更高版本,我的代码从一开始就是i18n 。

4

12 回答 12

91

简短的回答:

就像所有其他人已经写过的一样,很多程序员仍然使用 TCHAR 和相应的函数。在我看来,整个概念是个坏主意UTF-16字符串处理与简单的 ASCII/MBCS 字符串处理有很大不同。如果你对它们都使用相同的算法/函数(这是 TCHAR 想法的基础!),如果你做的不仅仅是简单的字符串连接(比如解析等)。主要原因是代理

唯一的例外是,当您确实必须为不支持 Unicode 的系统编译应用程序时,我认为没有理由在新应用程序中使用过去的这种包袱。

于 2008-11-26T20:46:42.813 回答
82

我必须同意萨沙。TCHAR// etc的底层前提_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除非你想自己定义它。

我推荐什么而不是 TCHAR

忘记存在“ANSI”编码,除非您需要读取无效的 UTF-8 文件。也别想TCHAR了。始终调用“W”版本的 Windows API 函数。 #define _UNICODE只是为了确保您不会意外调用“A”函数。

始终对字符串使用 UTF 编码:对字符串使用 UTF-8,对char字符串使用 UTF-16(在 Windows 上)或 UTF-32(在类 Unix 系统上)wchar_ttypedef UTF16UTF32字符类型以避免平台差异。

于 2010-06-09T01:12:07.760 回答
18

如果您想知道它是否仍在实践中,那么是的 - 它仍然被使用了很多。如果你的代码使用了 TCHAR 和 _T(""),没有人会觉得你的代码很有趣。我现在正在进行的项目正在从 ANSI 转换为 unicode - 我们正在采用可移植 (TCHAR) 路线。

然而...

我的投票是忘记所有 ANSI/UNICODE 可移植宏(TCHAR、_T("") 和所有 _tXXXXXX 调用等...),而只是假设到处都是 unicode。如果您永远不需要 ANSI 版本,我真的看不出便携的意义。我会直接使用所有宽字符函数和类型。在所有字符串文字前加上 L。

于 2008-10-24T17:19:04.763 回答
15

如果我今天做一个新项目,我仍然会使用 TCHAR 语法。使用它和 WCHAR 语法之间没有太大的实际区别,我更喜欢在字符类型是什么方面明确的代码。由于大多数 API 函数和辅助对象采用/使用 TCHAR 类型(例如:CString),因此使用它才有意义。此外,如果您决定在某个时候在 ASCII 应用程序中使用代码,或者 Windows 曾经演变为 Unicode32 等,它还为您提供了灵活性。

如果您决定走 WCHAR 路线,我会明确说明。也就是说,使用 CStringW 代替 CString,并在转换为 TCHAR 时转换宏(例如:CW2CT)。

无论如何,这是我的看法。

于 2008-10-24T17:32:25.233 回答
11

MSDN 上的Windows 编程简介文章

新应用程序应始终调用(API 的)Unicode 版本。

TEXTTCHAR宏现在用处不大,因为所有应用程序都应该使用 Unicode 。

我会坚持wchar_tL""

于 2010-08-14T16:49:22.613 回答
11

我想提出一种不同的方法(两者都不是)。

总而言之,使用 char* 和 std::string,假设 UTF-8 编码,并且仅在包装 API 函数时才转换为 UTF-16。

Windows 程序中这种方法的更多信息和理由可以在http://www.utf8everywhere.org中找到。

于 2012-01-24T17:54:00.230 回答
8

TCHAR/WCHAR对于一些遗留项目来说可能就足够了。但是对于新的应用程序,我会说NO

由于历史原因,所有这些TCHAR/东西都在那里。提供了一种看似巧妙的方式(伪装)在 ANSI 文本编码 (MBCS) 和 Unicode 文本编码 (UTF-16) 之间切换。过去,人们并不了解世界上所有语言的字符数。他们假设 2 个字节足以表示所有字符,因此具有使用. 然而,在1996 年Unicode 2.0 发布后,情况就不再如此了。WCHARTCHARWCHAR

也就是说:无论你在CHAR/ WCHAR/TCHAR中使用哪个,你程序中的文本处理部分都应该能够处理变长字符以进行国际化。

所以你实际上需要做的不仅仅是从CHAR//WCHAR中选择一个TCHAR在Windows中进行编程:

  1. 如果您的应用程序很小并且不涉及文本处理(即只是将文本字符串作为参数传递),那么坚持使用WCHAR. 因为这种方式更容易使用支持 Unicode 的 WinAPI。
  2. 否则,我建议使用 UTF-8 作为内部编码并将文本存储在 char 字符串或 std::string 中。并在调用 WinAPI 时将它们转换为 UTF-16。UTF-8现在是主要的编码,并且有许多方便的库和工具来处理 UTF-8 字符串。

查看这个精彩的网站以获得更深入的阅读: http ://utf8everywhere.org/

于 2015-03-15T02:45:33.620 回答
4

是的,一点没错; 至少对于 _T 宏。不过,我不太确定宽字符的东西。

原因是为了更好地支持 WinCE 或其他非标准 Windows 平台。如果您 100% 确定您的代码将保留在 NT 上,那么您可能只使用常规的 C 字符串声明。但是,最好倾向于更灵活的方法,因为在非 Windows 平台上#define 该宏要容易得多,而不是通过数千行代码并将其添加到任何地方,以防您需要移植一些库到windows手机。

于 2008-10-24T17:07:18.030 回答
2

恕我直言,如果您的代码中有 TCHAR,那么您在错误的抽象级别上工作。

在处理文本处理时使用对您最方便的任何字符串类型 - 希望这将支持 unicode,但这取决于您根据需要在 OS API 边界进行转换。

处理文件路径时,请创建自己的自定义类型,而不是使用字符串。这将允许您独立于操作系统的路径分隔符,将为您提供比手动字符串连接和拆分更容易的编码接口,并且更容易适应不同的操作系统(ansi、ucs-2、utf-8 等) .

于 2010-08-26T07:31:27.420 回答
2

我看到使用除显式 WCHAR 之外的任何东西的唯一原因是可移植性和效率。

如果您想让最终的可执行文件尽可能小,请使用 char。

如果您不关心 RAM 的使用并希望国际化像简单的翻译一样简单,请使用 WCHAR。

如果您想让您的代码灵活,请使用 TCHAR。

如果您只打算使用拉丁字符,您不妨使用 ASCII/MBCS 字符串,这样您的用户就不需要那么多 RAM。

对于“从一开始就是 i18n”的人来说,节省源代码空间并简单地使用所有 Unicode 函数。

于 2012-01-06T03:24:37.827 回答
-1

只是添加一个老问题:

在 VS2010 中开始一个新的 CLR C++ 项目。微软自己使用L"Hello World",'nuff 说。

于 2010-06-25T12:45:09.500 回答
-1

TCHAR有一个新的含义 to port from WCHARto CHAR

https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/use-utf8-code-page

最新版本的 Windows 10使用 ANSI 代码页和 -A API 作为向应用程序引入 UTF-8 支持的一种方式。如果为 UTF-8 配置 ANSI 代码页,则 -A API 以 UTF-8 运行。

于 2020-05-07T21:18:23.413 回答