我无法理解std::string和std::wstring之间的区别。我知道wstring支持Unicode字符等宽字符。我有以下问题:
什么时候应该使用std::wstring而不是std::string?std::string可以保存整个ASCII字符集,包括特殊字符吗?所有流行的C++编译器都支持std::wstring吗?什么是“宽字符”?
我无法理解std::string和std::wstring之间的区别。我知道wstring支持Unicode字符等宽字符。我有以下问题:
什么时候应该使用std::wstring而不是std::string?std::string可以保存整个ASCII字符集,包括特殊字符吗?所有流行的C++编译器都支持std::wstring吗?什么是“宽字符”?
当前回答
我经常使用std::string来保存utf-8字符,而没有任何问题。我强烈建议在与使用utf-8作为本机字符串类型的API接口时这样做。
例如,当我的代码与Tcl解释器接口时,我使用utf-8。
主要的警告是std::字符串的长度,不再是字符串中的字符数。
其他回答
什么时候不应该使用宽字符?
当你在1990年之前编写代码时。
很明显,我很生气,但事实上,现在是21世纪。127个字符早已不再足够。是的,你可以使用UTF8,但为什么要头疼呢?
当您希望在字符串中存储宽字符时。宽取决于实现。如果我没记错的话,Visual C++默认为16位,而GCC默认值取决于目标。这里有32位长。请注意wchar_t(宽字符类型)与unicode无关。它只是保证它可以存储实现所支持的最大字符集的所有成员,并且至少可以存储char。也可以使用utf-8编码将unicode字符串精细地存储到std::string中。但它无法理解unicode代码点的含义。因此str.size()不会给出字符串中逻辑字符的数量,而只给出该字符串/wstring中存储的char或wchar_t元素的数量。出于这个原因,gtk/glib C++包装人员开发了一个可以处理utf-8的glib::ustring类。如果wchar_t是32位长,那么可以使用utf-32作为unicode编码,并且可以使用固定(utf-32是固定长度)编码来存储和处理unicode字符串。这意味着wstring的s.size()函数将返回正确数量的wchar_t元素和逻辑字符。是的,char总是至少8位长,这意味着它可以存储所有ASCII值。是的,所有主要的编译器都支持它。
我经常使用std::string来保存utf-8字符,而没有任何问题。我强烈建议在与使用utf-8作为本机字符串类型的API接口时这样做。
例如,当我的代码与Tcl解释器接口时,我使用utf-8。
主要的警告是std::字符串的长度,不再是字符串中的字符数。
1) 正如Greg所提到的,wstring有助于国际化,这意味着您将以英语以外的语言发布产品
4) 检查此项以获取宽字符http://en.wikipedia.org/wiki/Wide_character
我建议避免在Windows或其他地方使用std::wstring,除非接口需要,或者在Windows API调用和相应编码转换附近的任何地方使用。
我的观点总结在http://utf8everywhere.org我是其中的一位合著者。
除非您的应用程序是以API调用为中心的,例如主要是UI应用程序,否则建议将Unicode字符串存储为std::string并以UTF-8编码,在API调用附近执行转换。本文概述的好处超过了转换的明显烦恼,尤其是在复杂的应用程序中。对于多平台和图书馆开发来说,这是双重的。
现在,回答您的问题:
一些薄弱的原因。它的存在是出于历史原因,人们认为宽字符是支持Unicode的正确方式。它现在被用于接口更喜欢UTF-16字符串的API。我只在这些API调用的直接附近使用它们。这与std::string无关。它可以保存你放入的任何编码。唯一的问题是你如何对待它的内容。我的建议是UTF-8,因此它将能够正确保存所有Unicode字符。这是Linux上的常见做法,但我认为Windows程序也应该这样做。不宽字符是一个令人困惑的名称。在Unicode的早期,人们相信一个字符可以用两个字节编码,因此得名。今天,它代表“字符的任何两个字节长的部分”。UTF-16被视为此类字节对的序列(也称为宽字符)。UTF-16中的字符采用一对或两对。