std :: wstring VS std :: string
  我无法理解std::string和std::wstring之间的区别。  我知道wstring支持宽字符,如Unicode字符。  我有以下问题: 
std::wstring不是std::string ? std::string保存整个ASCII字符集,包括特殊字符吗? std::wstring吗?   string ?  wstring ? 
  std::string是在char上模板化的basic_string ,在wchar_t上是std::wstring 。 
  char与wchar_t 
  char应该包含一个字符,通常是1个字节的字符。  wchar_t应该保持宽字符,然后,事情变得棘手:在Linux上, wchar_t是4个字节,而在Windows上,它是2个字节 
那么Unicode呢呢?
  问题是char和wchar_t都不直接绑定到unicode。 
在Linux上?
让我们来看一个Linux操作系统:我的Ubuntu系统已经知道了unicode。 当我使用char字符串时,它本地编码为UTF-8(即字符串的Unicode字符串)。 以下代码:
#include <cstring>
#include <iostream>
int main(int argc, char* argv[])
{
   const char text[] = "olé" ;
   std::cout << "sizeof(char)    : " << sizeof(char) << std::endl ;
   std::cout << "text            : " << text << std::endl ;
   std::cout << "sizeof(text)    : " << sizeof(text) << std::endl ;
   std::cout << "strlen(text)    : " << strlen(text) << std::endl ;
   std::cout << "text(bytes)     :" ;
   for(size_t i = 0, iMax = strlen(text); i < iMax; ++i)
   {
      std::cout << " " << static_cast<unsigned int>(
                              static_cast<unsigned char>(text[i])
                          );
   }
   std::cout << std::endl << std::endl ;
   // - - - 
   const wchar_t wtext[] = L"olé" ;
   std::cout << "sizeof(wchar_t) : " << sizeof(wchar_t) << std::endl ;
   //std::cout << "wtext           : " << wtext << std::endl ; <- error
   std::cout << "wtext           : UNABLE TO CONVERT NATIVELY." << std::endl ;
   std::wcout << L"wtext           : " << wtext << std::endl;
   std::cout << "sizeof(wtext)   : " << sizeof(wtext) << std::endl ;
   std::cout << "wcslen(wtext)   : " << wcslen(wtext) << std::endl ;
   std::cout << "wtext(bytes)    :" ;
   for(size_t i = 0, iMax = wcslen(wtext); i < iMax; ++i)
   {
      std::cout << " " << static_cast<unsigned int>(
                              static_cast<unsigned short>(wtext[i])
                              );
   }
   std::cout << std::endl << std::endl ;
   return 0;
}
输出以下文本:
sizeof(char)    : 1
text            : olé
sizeof(text)    : 5
strlen(text)    : 4
text(bytes)     : 111 108 195 169
sizeof(wchar_t) : 4
wtext           : UNABLE TO CONVERT NATIVELY.
wtext           : ol�
sizeof(wtext)   : 16
wcslen(wtext)   : 3
wtext(bytes)    : 111 108 233
  你会看到char的“olé”文本是由四个字符构成的:110,108,195和169(不包括结尾的零)。  (我会让你学习wchar_t代码作为练习) 
所以,在Linux上使用char时,通常应该在不知道它的情况下使用Unicode。 由于std :: string与char一起工作,所以std :: string已经准备好了。
请注意,std :: string与C字符串API一样,会认为“olé”字符串有4个字符,而不是3个字符。 所以在截断/播放unicode字符时应该小心谨慎,因为在UTF-8中禁止使用某些字符组合。
在Windows上?
  在Windows上,这有点不同。  在Unicode出现之前,Win32必须支持大量的应用程序,使用char和全世界生成的不同字符集/代码页。 
  所以他们的解决方案非常有趣:如果应用程序使用char ,那么char字符串将使用本地字符集/代码页在机器上编码/打印/显示在GUI标签上。  例如,“olé”在法语本地化的Windows中将是“olé”,但在西里尔语本地化的Windows上(如果使用Windows-1251,则为“olé”)。  因此,“历史应用程序”通常仍然以旧的方式工作。 
  对于基于Unicode的应用程序,Windows使用宽度为2个字节的wchar_t ,并以UTF-16编码,该编码采用2字节字符的Unicode编码(或者至少是大多数兼容的UCS-2,这几乎是同样的事情IIRC)。 
  使用char应用程序被称为“多字节”(因为每个字形都由一个或多个char组成),而使用wchar_t应用程序称为“widechar”(因为每个字形都由一个或两个wchar_t 。请参阅MultiByteToWideChar和WideCharToMultiByte Win32转换API获取更多信息。 
  因此,如果你在Windows上工作,你很想使用wchar_t (除非你使用隐藏GTK +或QT的框架)。  事实是,在幕后,Windows配合使用wchar_t字符串,因此,即使历史的应用也会有他们的char在转换字符串wchar_t使用像SetWindowText函数API时(低级别API函数来设置标签上一个Win32 GUI)。 
内存问题?
UTF-32每个字符4个字节,因此没有太多要添加的内容,只要UTF-8文本和UTF-16文本总是使用少于或等于UTF-32文本的内存量(通常较少)。
如果存在内存问题,那么您应该比大多数西方语言知道,UTF-8文本将使用比相同的UTF-16更少的内存。
尽管如此,对于其他语言(中文,日文等),所使用的内存将相同,或者对于UTF-8比UTF-16更大。
总而言之,UTF-16将主要使用每个字符2个字节(除非你正在处理某种深奥的语言符号(Klingon?Elvish?),而UTF-8将花费1到4个字节。
有关更多信息,请参见http://en.wikipedia.org/wiki/UTF-8#Compared_to_UTF-16。
结论
1.当我应该使用std :: wstring over std :: string?
  在Linux上?  几乎从不 (§)。 
  在Windows上?  几乎总是 (§)。 
  在跨平台的代码?  取决于你的工具包... 
(§):除非您使用工具包/框架否则
2. std :: string是否可以保存包含特殊字符的所有ASCII字符集?
注意:std :: string适用于存放'binary'缓冲区,其中std :: wstring不是!
  在Linux上?  是。 
  在Windows上?  只有Windows用户的当前语言环境可用的特殊字符。 
编辑(在来自Johann Gerell的评论之后):std :: string将足以处理所有基于char的字符串(每个char是从0到255的数字)。 但:
3.几乎所有流行的C ++编译器都支持std :: wstring吗?
  大多数情况下,除了基于GCC的编译器移植到Windows之外 
  它适用于我的g ++ 4.3.2(在Linux下),并且自从Visual C ++ 6开始在Win32上使用Unicode API。 
4.什么是宽字符?
  在C / C ++上,它是一个写入wchar_t的字符类型,它比简单的char字符类型更大。  它应该用于放置其索引(如Unicode字形)大于255(或127,取决于...)的字符。 
  我建议在Windows或其他地方避免使用std::wstring ,除非接口要求或Windows API调用附近的任何位置以及各自的编码转换作为语法糖。 
我的观点总结在http://utf8everywhere.org,其中我是合着者。
除非您的应用程序是以API为中心的,例如主要是UI应用程序,否则建议将Unicode字符串存储在std :: string中,并以UTF-8编码,在API调用附近执行转换。 文章中概述的好处胜过转换的明显烦恼,特别是在复杂的应用程序中。 对于多平台和图书馆开发来说这是双重的。
现在,回答你的问题:
所以,这里的每个读者现在都应该清楚地了解事实和情况。 如果没有,那么你必须阅读paercebal的杰出全面的答案 [顺便说一句:谢谢!]。
我的实用结论非常简单:所有C ++(和STL)“字符编码”的东西实质上已经被破坏和无用。 把它归咎于微软或没有,这无济于事。
经过深入调查后,我的解决方案经历了许多挫折和相应的经验:
接受,你必须自己负责编码和转换的东西(你会看到它的很多都是微不足道的)
  对任何UTF-8编码的字符串使用std :: string(只是一个typedef std::string UTF8String ) 
接受这样一个UTF8String对象只是一个愚蠢的,但便宜的容器。 永远不要直接访问和/或操作字符(不搜索,替换等)。 你可以,但你真的只是真的,真的不想浪费时间为多字节字符串编写文本操作算法! 即使其他人已经做了这种愚蠢的事情,不要这样做! 随它去! (好吧,有些情况下它是有道理的......只是使用那些ICU库)。
  对于UCS-2编码的字符串使用std :: wstring( typedef std::wstring UCS2String ) - 这是一种妥协,并且是对WIN32 API引入的混乱的让步)。  UCS-2对于我们大多数人来说已经足够了(更多关于......)。 
每当需要逐个字符的访问时使用UCS2String实例(读取,操作等)。 任何基于字符的处理应该以非多字节表示方式完成。 它很简单,快速,简单。
添加两个实用函数来在UTF-8和UCS-2之间来回转换:
UCS2String ConvertToUCS2( const UTF8String &str );
UTF8String ConvertToUTF8( const UCS2String &str );
转换很简单,谷歌应该在这里帮助...
而已。 使用UTF8String,无论内存是珍贵的还是适用于所有UTF-8 I / O。 无论何处必须解析和/或操纵字符串,都使用UCS2String。 您可以随时在这两种表示之间进行转换。
替代品和改进
  可以在普通转换表的帮助下实现从&到单字节字符编码(例如ISO-8859-1)的转换,例如const wchar_t tt_iso88951[256] = {0,1,2,...};  以及适用于从UCS2转换为&的适当代码。 
  如果UCS-2不足,则切换到UCS-4( typedef std::basic_string<uint32_t> UCS2String ) 
ICU或其他unicode库?
先进的东西。
链接地址: http://www.djcxy.com/p/5055.html