c – std :: wstring VS std :: string
作者:互联网
我无法理解std :: string和std :: wstring之间的区别.我知道wstring支持Unicode字符等宽字符.我有以下问题:
>我什么时候应该在std :: string上使用std :: wstring?
> std :: string可以保存整个ASCII字符集,包括特殊字符吗?
>所有流行的C编译器都支持std :: wstring吗?
>什么是“广角”?
解决方法:
串? wstring的?
std :: string是在char上模板化的basic_string
,在wchar_t
上是std :: wstring.
char与wchar_t
char应该包含一个字符,通常是一个8位字符.
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(ordinals) :" ;
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(ordinals) :" ;
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(ordinals) : 111 108 195 169
sizeof(wchar_t) : 4
wtext : UNABLE TO CONVERT NATIVELY.
wtext : ol�
sizeof(wtext) : 16
wcslen(wtext) : 3
wtext(ordinals) : 111 108 233
你会看到char中的“olé”文本实际上由四个字符构成:110,108,195和169(不包括尾随零). (我会让你研究wchar_t代码作为练习)
因此,在Linux上使用char时,通常应该最终使用Unicode而不知道它.并且由于std :: string与char一起使用,所以std :: string已经是unicode-ready.
请注意,与C字符串API一样,std :: string会将“olé”字符串视为包含4个字符,而不是3个字符.因此,在截断/播放unicode字符时应该谨慎,因为在UTF-8中禁止使用某些字符组合.
在Windows上?
在Windows上,这有点不同.在Unicode出现之前,Win32必须支持许多使用char和在全世界生产的不同charsets/codepages上的应用程序.
因此,他们的解决方案很有趣:如果应用程序使用char,则使用计算机上的本地字符集/代码页在GUI标签上编码/打印/显示字符串.例如,“olé”在法语本地化的Windows中将是“olé”,但在西里尔语本地化的Windows上会有所不同(如果使用Windows-1251,则为“ol”).因此,“历史应用程序”通常仍然以相同的方式工作.
对于基于Unicode的应用程序,Windows使用wchar_t,它是2字节宽,并在UTF-16中编码,它是以2字节字符进行Unicode编码(或者至少是大多数兼容的UCS-2,几乎相同事IIRC).
使用char的应用程序称为“多字节”(因为每个字形由一个或多个字符组成),而使用wchar_t的应用程序称为“widechar”(因为每个字形由一个或两个wchar_t组成.请参阅MultiByteToWideChar和WideCharToMultiByte Win32转换API以获取更多信息.
因此,如果你在Windows上工作,你真的很想使用wchar_t(除非你使用隐藏它的框架,如GTK+或QT ……).事实是,在幕后,Windows使用wchar_t字符串,因此即使历史应用程序在使用像SetWindowText()(用于在Win32 GUI上设置标签的低级API函数)之类的API时也会在wchar_t中转换其char字符串.
记忆问题?
UTF-32每个字符有4个字节,所以没有太多要添加,只要UTF-8文本和UTF-16文本总是使用比UTF-32文本更少或相同的内存量(通常更少) ).
如果存在内存问题,那么您应该知道,对于大多数西方语言,UTF-8文本将使用比相同UTF-16文本更少的内存.
但是,对于其他语言(中文,日文等),UTF-8使用的内存要么相同,要么略大于UTF-16.
总而言之,UTF-16主要使用每个字符2个和偶尔4个字节(除非你正在处理某种深奥的语言字形(Klingon?Elvish?),而UTF-8将花费1到4个字节.
有关详细信息,请参阅http://en.wikipedia.org/wiki/UTF-8#Compared_to_UTF-16.
结论
>什么时候我应该使用std :: wstring而不是std :: string?
在Linux上?几乎从不 (§).
在Windows上?几乎总是 (§).
在跨平台代码?取决于你的工具包……
(§):除非您使用工具包/框架另有说法
> std :: string可以保存包含特殊字符的所有ASCII字符集吗?
注意:std :: string适合保存’二进制’缓冲区,其中std :: wstring不是!
在Linux上?是.
在Windows上?只有特殊字符可用于Windows用户的当前区域设置.
编辑(在Johann Gerell发表评论后):
一个std :: string就足以处理所有基于字符的字符串(每个字符串都是0到255之间的数字).但:
> ASCII应该从0到127.更高的字符不是ASCII.
>将正确保存0到127之间的字符
> 128到255之间的字符将具有取决于您的编码(unicode,非unicode等)的含义,但只要它们以UTF-8编码,它就能够保存所有Unicode字形.
>几乎所有流行的C编译器都支持std :: wstring吗?
大多数情况下,除了移植到Windows的基于GCC的编译器.
它适用于我的4.3.2版(在Linux下),自Visual C 6以来我在Win32上使用了Unicode API.
>什么是广泛的角色?
在C/C++上,它是一个写成wchar_t的字符类型,它比简单的char字符类型大.它应该用于放置其索引(如Unicode字形)大于255(或127,取决于…)的字符.
标签:c,string,unicode,wstring,c-faq 来源: https://codeday.me/bug/20190911/1802819.html