我无法理解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吗?什么是“宽字符”?
当前回答
当您希望使用Unicode字符串而不仅仅是ascii时,这有助于国际化是的,但它与0的配合不好没有意识到宽字符是编译器特有的处理unicode字符固定长度表示的方式,对于MSVC,它是2字节字符,对于gcc,我理解它是4字节。以及+1表示http://www.joelonsoftware.com/articles/Unicode.html
其他回答
如果保持字符串的可移植性,则可以使用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());
}
我经常使用std::string来保存utf-8字符,而没有任何问题。我强烈建议在与使用utf-8作为本机字符串类型的API接口时这样做。
例如,当我的代码与Tcl解释器接口时,我使用utf-8。
主要的警告是std::字符串的长度,不再是字符串中的字符数。
1) 正如Greg所提到的,wstring有助于国际化,这意味着您将以英语以外的语言发布产品
4) 检查此项以获取宽字符http://en.wikipedia.org/wiki/Wide_character
一个好问题!我认为数据编码(有时还涉及字符集)是一种内存表达机制,用于将数据保存到文件或通过网络传输数据,因此我将这个问题回答为:
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)
所以,现在在座的每一位读者都应该清楚地了解事实和情况。如果没有,那么你必须阅读帕塞巴尔非常全面的回答[顺便说一句:谢谢!]。
我的务实结论非常简单:所有C++(和STL)“字符编码”的东西基本上都是残缺不全的。不管是否归咎于微软,这都无济于事。
经过深入调查后,我的解决方案是:
接受,你必须自己负责编码和转换的事情(你会发现很多事情都很琐碎)对任何UTF-8编码字符串使用std::string(仅为typedef std::字符串UTF8String)接受这样一个UTF8String对象只是一个愚蠢但廉价的容器。永远不要直接访问和/或操作其中的字符(不要搜索、替换等)。你可以,但你真的不想浪费时间为多字节字符串编写文本操作算法!即使其他人已经做了如此愚蠢的事情,也不要这样做!顺其自然!(好吧,在某些情况下,这是合理的……只需使用ICU图书馆即可)。对UCS-2编码字符串使用std::wstring(typedef std::wstring UCS2String)-这是一种妥协,也是对WIN32 API引入的混乱的让步)。UCS-2对我们大多数人来说已经足够了(稍后将详细介绍…)。每当需要逐字符访问(读取、操作等)时,请使用UCS2String实例。任何基于字符的处理都应该在非多字节表示中完成。它简单、快速、容易。添加两个实用函数以在UTF-8和UCS-2之间来回转换:UCS2字符串转换为UCS2(const UTF8String&str);UTF8字符串转换为UTF8(常量UCS2String&str);
转换很简单,谷歌应该在这里提供帮助。。。
就是这样。在内存非常宝贵的地方以及所有UTF-8 I/O都使用UTF8String。在必须解析和/或操作字符串的地方使用UCS2String。您可以随时在这两种表示之间进行转换。
替代方案和改进
从&到单字节字符编码(例如ISO-8859-1)的转换可以借助于普通转换表来实现,例如const wchar_ttt_iso88951[256]={0,1,2,…};以及用于转换到UCS2和从UCS2转换的适当代码。如果UCS-2不够,则切换到UCS-4(typedef std::basic_string<uint32_t>UCS2String)
ICU或其他unicode库?
先进的东西。