string转wchar_t*
首先介绍下wchar_t类型
一、wchar_t类型的由来
我们知道char类型变量可以存储一个字节的字符,它用来保存英文字符和标点符号是可以的,但是对于汉字、韩文以及日文这样的字符却不可以,因为汉字、韩文以及日文每一个文字都占据两个字节,为了解决这个问题,c++提出了wchar_t类型,称之为双字节类型,又称宽字符类型。二、下
二、下面是一个范例
1 int main(int argc, wchar_t* argv[])
2 {
3 //使用setlocale函数将本机的语言设置为中文简体
4 setlocale(LC_ALL,"chs");//LC_ALL表示设置所有的选项(包括金融货币、小数点,时间日期格式、语言字符串的使用习惯等),chs表示中文简体
5 wchar_t wt[] = L"中国你好!";//大写字母L告诉编译器为"中"字分配两个字节的空间
6 wcout<<wt<<endl;//使用wcout来代替cout输出宽字符,wcin类代替cin输入宽字符
7 cout<<wcslen(wt)<<endl;//wcslen输出宽字符串的长度,输出长度是5
8 cout<<sizeof(wt)<<endl;//输出长度是12个字节,最后的wchar_t类型的'\0'两个字节
9 return 0;
10 }
三、 和string类型之间的转换
方法1:string->wstring->wchar_t*
1 inline std::wstring to_wide_string(const std::string& input) //string to wstring
2 {
3 std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
4 return converter.from_bytes(input);
5 }
6 string str("你好中国");
7 wstring ws_str=to_wide_string(str);
8 const wchar_t* wc_str=ws_str.c_str();
方法2:字符串格式化(针对字符串变量)string->char->wchar_t*
1 string str("你好中国");
2 wchar_t * wc = new wchar_t[str.size()];
3 swprintf(wc,100,L"%S",str.c_str()); //注意大写
4 //wc指向的内存区域存储这wchar_t类型的 ”你好中国“。
方法3:
MultiByteToWideChar();
1 #include <windows.h>
2 #include <string>
3
4 //不要忘记在使用完wchar_t*后delete[]释放内存
5 wchar_t *multi_Byte_To_Wide_Char(const string& pKey)
6 {
7 //string 转 char*
8 char* pCStrKey = pKey.c_str();
9 //第一次调用返回转换后的字符串长度,用于确认为wchar_t*开辟多大的内存空间
10 int pSize = MultiByteToWideChar(CP_OEMCP, 0, pCStrKey, strlen(pCStrKey) + 1, NULL, 0);
11 wchar_t *pWCStrKey = new wchar_t[pSize];
12 //第二次调用将单字节字符串转换成双字节字符串
13 MultiByteToWideChar(CP_OEMCP, 0, pCStrKey, strlen(pCStrKey) + 1, pWCStrKey, pSize);
14 return pWCStrKey;
15 }
QString转wchar_t*
以下filename均为QString格式。
方法1:
1 file = filename.toStdWString();
2 const wchar_t* str1 = file.c_str();
Returns a std::wstring object with the data contained in this QString. The std::wstring is encoded in utf16 on platforms where wchar_t is 2 bytes wide (e.g. windows) and in ucs4 on platforms where wchar_t is 4 bytes wide (most Unix systems).
这是最朴素的想法。也是最好使用的办法。很奇怪的是,我前几次测试,却是debug看到了乱码,我也不确定是否是改动了其他宏或者build参数导致的。不过,后来的测试表明,这种方式才是正确的方式,可能存在的问题最小。
方法2:
1 wchar_t str2[256] = {0};
2 auto xxx = filename.toWCharArray(str2);
这种方法是查询QString 文档而知的。但是,这种方式要谨慎,若不对数组str2 初始化,debug可以看到字符串最后会多出来一两个字符,完全随机的。还要注意数组长度。
方法3:
const wchar_t * encodedName = reinterpret_cast<const wchar_t *>(filename.utf16());
虽然这种方法也能工作,但是需要注意。这里用到了强转,reinterpret_cast 表达式不会编译成任何 CPU 指令,它纯粹是一个编译时指令,指示编译器将 表达式 视为如同具有 新类型 类型一样处理。亦即,与C写法,(const wchar_t *)ptr 并没有什么不同。
其实,最重要的,我们还是需要知道 OS 使用的编码方式。
C:\Users\kt>chcp
活动代码页: 936
这就是 GB2312 了。每个汉字及符号以两个字节来表示。
Fills the array with the data contained in this QString object. The array is encoded in utf16 on platforms where wchar_t is 2 bytes wide (e.g. windows) and in ucs4 on platforms where wchar_t is 4 bytes wide (most Unix systems).
所以,方法3,只能在windows上使用,在Linux上,还需要注意。
至于从wchar_t* 转换为QString的方式,直接参看QString的接口,上述1、3方法对应的接口有fromStdWString、fromUtf16,应该可以解决问题。