何时应该使用宽字符字符串?

7

我正在现代化一个庞大的、传统的MFC代码库,其中包含各种字符串类型:

  • CString
  • std::string
  • std::wstring
  • char*
  • wchar_t*
  • _bstr_t

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

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

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


7
在Windows内部,字符编码使用的是UTF-16LE,因此在该平台上使用std::wstringstd::vector<wchar_t>都是很合适的选择。 - Richard Critten
3
对于Windows应用程序,请使用std::wstring。如果使用窄字符串,则需要在各处进行转换。请注意:既然您不知道这一点,您不是做这项工作的好选择,这是基础知识。选择您为翻译人员的责任在于您的经理。 - Cheers and hth. - Alf
2
关于 _T("Hello world"),自从引入 Unicode 层以来,T 宏已经在 2000 年被淘汰,而今天我们的工具无法为这些宏所针对的 Windows 版本(9x)生成可执行文件。我知道这是一个遗留代码库。但当你的任务是清理它时,提到 T 宏是不合适和非常低效的。 - Cheers and hth. - Alf
3
如果您选择窄字符,那么只需要一个非拉丁名字的员工,您的程序就会出现编码问题,影响用户和以下目录。 - Richard Critten
1
http://utf8everywhere.org/ - Artemy Vysotsky
显示剩余5条评论
2个回答

8
如果我们谈论Windows,那么我会使用std::wstring(因为我们经常需要很酷的字符串功能),或者wchar_t*(如果你只是传递字符串)。
请注意,Microsoft在这里推荐使用:Working with Strings

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

还有:

当Microsoft向Windows引入Unicode支持时,通过提供两组平行的API(一组用于ANSI字符串,另一组用于Unicode字符串)来简化过渡。[...]在内部,ANSI版本将字符串转换为Unicode。

还有:
新的应用程序应该始终调用Unicode版本。许多世界语言都需要Unicode。如果您使用ANSI字符串,将无法本地化您的应用程序。ANSI版本也不太高效,因为操作系统必须在运行时将ANSI字符串转换为Unicode。[...] Windows中的大多数较新的API仅具有Unicode版本,没有相应的ANSI版本。

4
因为我们经常需要一些酷炫的字符串功能,这部分内容可能需要更详细的说明。为什么不使用CString呢?MFC无处不在地使用它。虽然我不建议这样做;-) - zett42
@zett42 - 十年或二十年前(是的,我很老 :-),我也会推荐这样做,但今天,有那么多的示例/代码/开源等使用std::,而且有很多人习惯了它,所以我觉得std::也可以。然而,只要确保没有人因为懒惰而引入std::,我认为CString也完全可以。 - Simon Mourier
我想要补充一下,在OP的特定情况下,std::wstring是我认为最好的选择。但是,不要盲目决定总是使用std::wstring和宽字符。在做出选择之前,请考虑应用程序正在执行的操作。有趣的是,很多年前(大约在2000年初),我拿到了Dhrystone基准测试的源代码,并将其中每个“char”实例转换为“wchar_t”。这样做导致性能下降了约15%,因此请注意使用宽字符确实会付出代价。你需要自己决定是否在意这个代价。 - dgnuff

1
这要看情况。
在编写Windows程序时,建议至少使用std::wstring来处理以下内容:
- 资源(字符串、对话框等) - 文件系统访问(Windows允许在文件和目录名中使用非ASCII字符(包括所有“错误的撇号”),这些文件无法使用ANSI API打开) - COM(BSTR始终是宽字符) - 其他用户界面(剪贴板、系统错误报告等)
但是,使用单个字符字符串处理内部ASCII数据文件和UTF-8编码数据更加简单、快速和高效。
除了问题中未提及的其他方面,如数据库或使用的API、输入/输出文件等以及它们的字符集,在决定最佳数据结构时都起着重要作用。
“到处使用UTF-8”通常是一个好主意。但是没有任何Windows API支持UTF-8。即使std::experimental::filesystem API在Windows上也使用std::wstring,而在POSIX上则使用std::string

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接