【问题标题】:When should we prefer wide-character strings?我们什么时候应该更喜欢宽字符串?
【发布时间】:2018-02-09 12:54:15
【问题描述】:

我正在对一个大型的遗留 MFC 代码库进行现代化改造,其中包含真正的字符串类型混合体:

  • CString
  • std::string
  • std::wstring
  • 字符*
  • wchar_t*
  • _bstr_t

我想在内部标准化单个字符串类型,仅在第三方 API(即 COM 或 MFC 函数)绝对需要时转换为其他类型。我和我的同事正在辩论的问题;我们应该标准化哪种字符串类型?

我更喜欢 C++ 标准字符串之一:std::string 或 std::wstring。我个人倾向于 std::string,因为我们不需要宽字符——它是一个内部代码库,没有面向客户的 UI(即不需要多语言支持)。 “普通”字符串允许我们使用简单、朴素的字符串文字(“Hello world”与 L“Hello world”或 _T(“Hello world”))。

编程社区有官方立场吗?当面对多种字符串类型时,通常使用什么作为标准的“内部”存储格式?

【问题讨论】:

  • Windows 内部是 UTF-16LE,所以std::wstring 非常适合该平台; std::vector<wchar_t>也是如此。
  • 对于 Windows 应用程序,请使用 std::wstring。使用窄字符串,您需要到处进行转换。注意:由于您还不知道这一点,因此您不是做这项工作的好选择,这是基础知识。这个选择是你的经理的错。
  • Re _T("Hello world")T 宏在 2000 年因 Unicode 层的引入而被淘汰,今天我们的工具无法为这些 Windows 版本 (9x) 生成可执行文件宏目标。我知道这是一个遗留代码库。但是当你的任务是清理时,提到T 宏是很荒谬的,而且会适得其反。
  • 如果您选择窄字符,那么您只需要一名非拉丁名字的员工就可以破坏您的程序,并且您遇到了用户及以下目录的编码问题。
  • @BTownTKD;您的声明“Windows 为几乎所有 API 提供窄字符替代方案”是基于完全无知。窄函数执行与 Windows ANSI 之间的转换,这是 (1) 系统特定的,并且 (2) 无法表示例如所有文件系统路径。此外,许多 API,尤其是较新的 API,没有 ANSI 包装器。

标签: c++ string mfc com widestring


【解决方案1】:

如果我们谈论 Windows,我会使用 std::wstring(因为我们经常需要很酷的字符串功能),或者如果你只是传递字符串,我会使用 wchar_t*。

注意微软在这里推荐:Working with Strings

Windows 原生支持 UI 元素、文件名、 等等。 Unicode 是首选的字符编码,因为它 支持所有字符集和语言。 Windows 代表 Unicode 使用 UTF-16 编码的字符,其中每个字符都经过编码 作为 16 位值。 UTF-16 字符称为宽字符,以 将它们与 8 位 ANSI 字符区分开来。 Visual C++ 编译器 支持宽字符的内置数据类型 wchar_t

还有:

当 Microsoft 将 Unicode 支持引入 Windows 时,它简化了 通过提供两组并行 API 进行转换,一组用于 ANSI 字符串,另一个用于 Unicode 字符串。 [...] 在内部,ANSI version 将字符串转换为 Unicode。

还有:

新应用程序应始终调用 Unicode 版本。许多世界 语言需要 Unicode。如果您使用 ANSI 字符串,它将是 无法本地化您的应用程序。 ANSI 版本也是 效率较低,因为操作系统必须转换 ANSI 在运行时将字符串转换为 Unicode。 [...] Windows 中大多数较新的 API 都有 只是一个 Unicode 版本,没有对应的 ANSI 版本。

【讨论】:

  • 因为我们经常需要很酷的字符串特性 ...可以详细说明一下。为什么不改用CString,MFC 到处都用呢?我不建议这样做;-)
  • @zett42 - 10 或 20 年前(是的,我太老了 :-),我也曾推荐过,但是今天,有很多示例/代码/开源/等等。使用 std:: 以及很多人习惯了它,我对 std:: 感觉很好,但是,我认为 CString 也完全可以,只要你确保没有人因为懒惰而引入 std::...
【解决方案2】:

视情况而定。

在为 Windows 编程时,我建议至少将std::wstring 用于:

  • 资源(字符串、对话框等)
  • 文件系统访问(Windows 允许在文件和目录名称中使用非 ASCII 字符(包括所有“错误类型的撇号”顺便说一句),这些无法使用 ANSI API 打开)
  • COM(BSTR 始终是宽字符)
  • 其他面向用户的界面(剪贴板、系统错误报告等)

但是,使用单字符串处理内部 ASCII 数据文件UTF-8-encoded-data更容易。它快速、高效且直接。

问题中可能还没有提到其他方面,例如使用的数据库或 API、输入/输出文件等及其字符集 - 所有这些都在为工作。

“UTF-8 无处不在”通常是一个合理的想法。但是有 0 Windows API 采用 UTF-8。甚至 std::experimental::filesystem API 在 Windows 上使用 std::wstring 在 POSIX 上使用 std::string

【讨论】:

    猜你喜欢
    • 2018-01-22
    • 2022-01-08
    • 2011-05-10
    • 2016-05-20
    • 1970-01-01
    • 2017-12-21
    • 2011-09-11
    • 1970-01-01
    • 2020-07-19
    相关资源
    最近更新 更多