C++中文字符处理(宽字符转换)C++中文字符处理(宽字符转换)
std::string vs std::wstring
一般情况下,我们使用c++处理字符串都使用的是string来处理。但在处理中文时,string的一些方法不能达到我们想要的效果,比如:size()函数返回的是中文字符串所占的字节数。
1 2
| string s = "今天天气123"; cout << s.size() << endl;
|
而我们想要得到我们日常理解的字符数:7
这里我们使用宽字符就可以达到目的: 1 2
| wstring s = L"今天天气123"; cout << s.size() << endl;
|
下面就介绍一下如何使string与w_string进行互转: ###
c++11(gcc5以上版本)
在c++11中比较简单,直接使用std::wstring_convert()
函数就可以进行互转。例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <string> #include <locale> #include <codecvt>
std::wstring s2ws(const std::string& str) { using convert_typeX = std::codecvt_utf8<wchar_t>; std::wstring_convert<convert_typeX, wchar_t> converterX; return converterX.from_bytes(str); }
std::string ws2s(const std::wstring& wstr) { using convert_typeX = std::codecvt_utf8<wchar_t>; std::wstring_convert<convert_typeX, wchar_t> converterX; return converterX.to_bytes(wstr); }
|
但需要注意的是经常使用的gcc
4.8版本明确不支持这个函数,需要gcc
5才可以使用。所以本人没有具体验证过
(捂脸)。
gcc 4.8
对于gcc4.8就只能使用clib的函数来转换了。
主要用到的是:wcstombs() 和
mbstowcs()
wcstombs
函数说明:
std::wcstombs
#include
std::size_t wcstombs( char dst, const wchar_t src, std::size_t len);
从wchar_t* src转换成char*
dst,len为dst buffer的最大值。
返回值为转换的字节数(不包括\0),出错返回
-1.
举例
1 2 3 4 5 6 7 8 9 10 11 12
| #include <clocale> #include <cstdlib>
setlocale(LC_ALL, ""); wstring ws = L"今天天气"; cout << ws.size() << endl; int len = wcslen(ws.c_str()); cout << "wcslen:" << len << endl; char str_buf[100]; int n = wcstombs(str_buf, ws.c_str(), 100); string out = string(str_buf, n); cout << "w > s(" << out << "):" << out.size() << endl;
|
1 2 3
| 4 wcslen:4 w > s(今天天气):12
|
mbstowcs
函数说明:
std::mbstowcs
#include
std::size_t mbstowcs( wchar_t dst, const char src, std::size_t len);
从char* src转换到wchar_t*
dst,len为dst buffer的最大值。
返回值为宽字节个数(不包括\0),出错返回
-1。
举例
1 2 3 4 5 6 7 8 9 10
| #include <clocale> #include <cstdlib>
setlocale(LC_ALL, ""); string s = "今天天气123"; cout << s.size() << endl; wchar_t wstr_buf[100]; int m = mbstowcs(wstr_buf, s.c_str(), 100); wstring wout = wstring(wstr_buf, m); cout << "s > w:" << wout.size() << endl;
|
find举例
1 2 3 4 5 6 7 8 9 10 11 12 13
| wstring ws_q = L"天气"; size_t p = wout.find(ws_q); if (p != std::string::npos) { cout<< "ws find:" << p << endl; } else { cout<< "not find:" << p << endl; } string q = "天气"; size_t q_pos = s.find(q); if (q_pos != std::string::npos) { cout << "s find:" << q_pos << endl; }
|
wstring会直接返回中文字符数。string的find会返回实际字节数。
引用
How
to convert wstring into string?
std::codecvt_utf8
std::wstring_convert
Is
codecvt not a std header?
GCC 5 Release
Series: Changes, New Features, and Fixes
std::mbstowcs
std::wcstombs