将char转化为TCHAR
TCHAR在Unicode字符集下是wchar_t,wchar_t就是unsigned short,也就是一个字,在多字节字符集下是char。这里讨论在Unicode字符集下将wchar_t转化为char。
一开始只有char,char用ASCII编码,char只有128个编码,后来不够了,char变为256个编码,再后来各个国家基于ASCII出了各自国家文字的编码,中国的叫GBK,也就是国标码,并且这些编码有些占1字节,有些2字节,有些3字节,GBK占2字节,所有这些编码统称为多字节字符集,可以近似理解为ASCII码。
后来为了统一编码,出了Unicode字符集,这个字符集有三种编码形式UTF-8,UTF-16,UTF-32,分别用8位,16位,32位来表示码元。
具体的内容看https://zhuanlan.zhihu.com/p/165524551。
总之多字节字符集和Unicode是两种不同的字符集,没有什么好的方法能用一个函数表达式转换,只能用系统自带的资源一一对应去转换。
在Unicode字符集下将多字节字符集的单字节字符串转为宽字节字符串需要将ASCII码转为Unicode才能奏效,而在多字节字符集中没有这个顾虑。
转换的方法有两种:
第一种CRT库:
#include<stdlib.h> size_t mbstowcs(wchar_t* _Dest,const char* _Source, size_t _MaxCount); // mbs to wcs,MultiByteToWideChar的缩写,也就是多字节到宽字节 // 第一个参数是存放转换后的字符串的地址,第二个参数是转化前的字符串,第三个是存放转换后字符串的缓冲区大小 // 返回值为转化后字符串的长度 // 在Unicode字符集下,这种方法只能转化头127个ASCII码,不能转换国标码 size_t wcstombs(char* _Dest,const wchar_t* _Source,size_t _MaxCount); // 第一个参数为存放结果的地址 // 第二个参数为待转换的字符串 // 第三个参数为存放结果的地址的缓冲区大小 // 返回值为转化后字符串的长度 // 在Unicode字符集下,这种同样只能转化头127个ASCII码,不能转化其他东西
第二种WindowsAPI:
#include<Windows.h> int MultiByteToWideChar(UINT CodePage,DWORD dwFlags, LPCCH lpMultiByteStr,int cbMultiByte,LPWSTR lpWideCharStr,int cchWideChar); // 第一个参数是要转换的字符串用的字符编码, // 第二个参数是判断组合字符用的,传0就行, // 第三个参数是转换前的字符串地址, // 第四个参数是转化前的字符串长度 // 第五个参数是接受转化后的字符串的地址 // 第六个参数是接受转化后字符串的缓冲区长度
// 这个方法就能转换中文了
// 返回值是转化后的字符串长度
int WideCharToMultiByte(UINT CodePage,DWORD dwFlags, LPCWCH lpWideCharStr,int cchWideChar,LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar,LPBOOL lpUsedDefaultChar); // 第一个参数为原字符串所用的字符集 // 第二个参数是判断组合字符串用的,传0即可 // 第三个参数是要转换的字符串 // 第四个参数是要转换的字符串长度,传-1则自动算出要转换字符串长度 // 第五个参数是存放转换后字符串的地址 // 第六个参数是存放转后后字符串地址的缓冲区大小 // 第七个参数是要是有一些Unicode字符不能转化用于替换的字符的首地址,传NULL则替换为系统默认的字符 // 第八个参数是字符串中是否存在不能被转换的字符,是传TRUE,否传FALSE // 返回值是转化完的字符串长度
示例:
#include<stdlib.h> #include<Windows.h> using namespace std; int main() { WCHAR* arr = nullptr; //int len=wcstombs(NULL, L"helloworld", 0);// 示范 int len=mbstowcs(NULL, "helloworld", 0); arr = new WCHAR[len]; mbstowcs(arr, "helloworld", len); WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), arr, len, NULL, NULL); delete[] arr; // len=WideCharToMultiByte(CP_UTF8, 0, L"中国汉字牛逼",-1,NULL,0,NULL,FALSE ); //这个就是示范一下,没什么用 len=MultiByteToWideChar(CP_ACP, 0, "中国汉字牛逼", -1, NULL, 0); arr = new WCHAR[len]; MultiByteToWideChar(CP_ACP, 0, "中国汉字牛逼", -1, arr, len); WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), arr, len, NULL, NULL); delete[] arr; return 0; }