我无法理解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吗?什么是“宽字符”?
当前回答
一个好问题!我认为数据编码(有时还涉及字符集)是一种内存表达机制,用于将数据保存到文件或通过网络传输数据,因此我将这个问题回答为:
1.何时应该使用std::wstring而不是std::string?
如果编程平台或API函数是单字节的,并且我们想要处理或解析一些Unicode数据,例如从Windows的.REG文件或网络2字节流中读取的数据,那么我们应该声明std::wstring变量以方便处理它们。例如:wstring ws=L“中国a“(6个八位字节内存:0x4E2D 0x56FD 0x0061),我们可以使用ws[0]获取字符'中' 和ws[1]获取字符'国' 和ws[2]获取字符“a”等。
2.std::string是否可以保存整个ASCII字符集,包括特殊字符?
对但请注意:美国ASCII,意味着每个0x00~0xFF八位字节代表一个字符,包括可打印文本,如“123abc&*_&”,您所说的特殊文本,大多打印为“”避免混淆编辑器或终端。还有一些国家扩展了自己的“ASCII”字符集,例如中文,使用2个八位字节来表示一个字符。
3.所有流行的C++编译器都支持std::wstring吗?
也许,或者大部分。我使用过:VC++6和GCC 3.3,是
4.什么是“宽字符”?
宽字符主要表示使用2个八位字节或4个八位字符来容纳所有国家的字符。2个八位字节UCS2是一个代表性示例,此外,例如英语“a”,其内存为0x0061的2个八位数(而ASCII“a”的内存为1个八位位0x61)
其他回答
什么时候不应该使用宽字符?
当你在1990年之前编写代码时。
很明显,我很生气,但事实上,现在是21世纪。127个字符早已不再足够。是的,你可以使用UTF8,但为什么要头疼呢?
如果保持字符串的可移植性,则可以使用tstring,tchar。这是很久以前广泛使用的技术。在这个示例中,我使用了自定义的TCHAR,但您可以在internet上找到linux的TCHAR.h实现。
这个想法意味着windows上使用wstring/wchar_t/UTF-16,Linux上使用string/char/UTF-8(或ASCII..)。
在下面的示例中,英语/日语多字节混合字符串的搜索在两个windows/linux平台上都运行良好。
#include <locale.h>
#include <stdio.h>
#include <algorithm>
#include <string>
using namespace std;
#ifdef _WIN32
#include <tchar.h>
#else
#define _TCHAR char
#define _T
#define _tprintf printf
#endif
#define tstring basic_string<_TCHAR>
int main() {
setlocale(LC_ALL, "");
tstring s = _T("abcあいうえおxyz");
auto pos = s.find(_T("え"));
auto r = s.substr(pos);
_tprintf(_T("r=%s\n"), r.c_str());
}
当您希望在字符串中存储宽字符时。宽取决于实现。如果我没记错的话,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值。是的,所有主要的编译器都支持它。
如果应用程序不满足256个不同的字符,则可以选择使用宽字符(超过8位)或可变长度编码(C++术语中的多字节编码),如UTF-8。宽字符通常比可变长度编码需要更多的空间,但处理速度更快。处理大量文本的多语言应用程序通常在处理文本时使用宽字符,但在将文本存储到磁盘时将其转换为UTF-8。
字符串和wstring之间的唯一区别是它们存储的字符的数据类型。字符串存储的字符大小保证至少为8位,因此您可以使用字符串来处理例如ASCII、ISO-8859-15或UTF-8文本。该标准没有说明字符集或编码。
实际上,每个编译器都使用一个字符集,其前128个字符与ASCII对应。使用UTF-8编码的编译器也是如此。在UTF-8或其他可变长度编码中使用字符串时,需要注意的重要一点是,索引和长度是以字节而不是字符来度量的。
wstring的数据类型是wchar_t,其大小在标准中没有定义,除了它必须至少与一个字符一样大,通常是16位或32位。wstring可用于处理实现定义的宽字符编码中的文本。因为标准中没有定义编码,所以在字符串和wstring之间进行转换并不简单。也不能假设wstring具有固定长度编码。
如果您不需要多语言支持,那么可以只使用常规字符串。另一方面,如果您正在编写图形应用程序,则API通常只支持宽字符。然后,您可能希望在处理文本时使用相同的宽字符。请记住,UTF-16是一种可变长度编码,这意味着您不能假定length()返回字符数。如果API使用固定长度编码,例如UCS-2,则处理变得容易。在宽字符和UTF-8之间进行转换很难以可移植的方式进行,但话说回来,您的用户界面API可能支持这种转换。
要存储“宽”(Unicode)字符时。是:其中255个(不包括0个)。对这是一篇介绍性文章:http://www.joelonsoftware.com/articles/Unicode.html