【问题标题】:Mapping format specifiers when Unicode is defined in C++?在 C++ 中定义 Unicode 时映射格式说明符?
【发布时间】:2016-02-02 14:44:54
【问题描述】:

_tprintf() 映射到wprintf() 时,将格式说明符%s 映射到%ls

我正在使用 _T() 宏将字符串映射到 ASCII 或 Unicode,具体取决于是否定义了 _UNICODE

但是,像_tprintf("%s", _T("text string")) 这样的调用给我带来了麻烦,因为在定义_UNICODE 时类型不一致。

我看到 %ls 应该用于 Unicode 字符串。

在定义_UNICODE 时,如何将%s 直接映射到%ls?有没有像_T()?这样的花哨功能

【问题讨论】:

标签: c++ windows format-specifiers tchar


【解决方案1】:

但是,像_tprintf("%s", _T("text string")) 这样的电话让我 麻烦,因为在定义_UNICODE 时类型不一致。

您也应该将 _T() 装饰器用于_tprintf() 的第一个字符串文字(即格式说明符字符串):

// NOTE: _T("%s"), not just "%s"
//
_tprintf(_T("%s"), _T("text string"));

这在 ANSI 版本中扩展为:

printf("%s", "text string"); // %s maps to char* ANSI string

在 Unicode 中构建为:

wprintf(L"%s", L"text string"); // %s maps to wchar_t* Unicode string

【讨论】:

  • 那么 %ls 说明符呢? %s 对于 Unicode 是否足够?
  • @NicolasLykkeIversen:在 Unicode 构建中,%s 映射到 wchar_t* Unicode 字符串。在 ANSI 版本中,%s 映射到 char* ANSI 字符串。就这么简单。还是我从你的问题中遗漏了什么?
  • 那么说明符 %ls 和 %S 是干什么用的? %s 说明符在 wprint() 的上下文中被解释为 Unicode,而在 printf() 的上下文中被解释为 ASCII?还是编译器做了什么特别的事情?
  • 另外,_T() 和 _tprintf() 是 Windows 特定的吗?
  • @NicolasLykkeIversen:是的,_T()_tprintf() 是特定于 Windows 的(所谓的“TCHAR 模型”也是它们的一部分)。在现代 C++/Win32 代码中,我建议只使用 Unicode,并避免 TCHAR 模型的整体复杂性(这是为了向后兼容过时的 ANSI 版本)。
【解决方案2】:

解决方法是不要使用_tprintf,而是使用std::wcout

  1. wcout 支持 ansi 字符和wchar_t 字符
  2. wcoutXXXprintf 更安全,因为它“知道”应该打印什么样的参数(避免像 printf("%s",'a'); 这样的惨败)
  3. 它是可移植的,而 _tprintf 不是
  4. 它是多态的,可以与其他流(如fstream 等)一起使用,_tprintf 不是。

xxxcout 的唯一缺点是它会使可执行文件有点膨胀,并且比 printf 家族要慢一些,但我真的相信它在你的应用程序中会是任何真正的缺点。

放弃 printf 之类的函数,转而使用 C++ 流。

【讨论】:

  • 那么 wcout 打印 ASCII 和 Unicode 都没有问题吗?那为什么要使用 cout 呢?如果定义了 _UNICODE,wcout 是否会映射到 _tprintf() 之类的东西?
  • @NicolasLykkeIversen:“那为什么要使用 cout?”因为很多非 Microsoft 世界都使用 UTF-8,而他们的 wchar_t 是一个完整的 4 个字节。
  • does wcout gets mapped to something like _tprintf() if _UNICODE is defined? 它使用重载,这是一种 C++ 机制来完成通用代码(以及许多其他代码)
  • 因此,如果我在同一个 C++ 程序中有一个 ASCII 字符串和一个 Unicode 字符串,那么 wcout 应用于这些字符串,如 wcout
  • 没错,这个:std::wcout<< "hello " << L"world"; 工作正常,没有任何问题
猜你喜欢
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-19
  • 2018-07-01
  • 1970-01-01
相关资源
最近更新 更多