十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

C++中的字符编码方式

C++中的字符编码方式 目录1.char2.wchar_t3.TCHAR4.一些函数1.char 转化为 16进制字符串2.字符串的UTF-8与GBK(或GB2312)编码转换C基本数据类型中表示字符的有两种基本类型char、wchar_t。区别于C#中的char和string 见文章C#中的字符编码方式以及一些字符集相关的函数_c# 字符串编码_ivy_0709的博客-CSDN博客1.char基本类型的本质就是在内存中是怎么存储怎么表示这个值的。本质上char基本类型在内存中存的就是一个8个bit比如01010101的值至于怎么解析这个值这个值代表什么字符怎么显示给你看的就是有一个对应的字符编码表了。所以一个char占一个字节8bit。但是不是一个字符都是一个char中文字符占用的是2个字节即2个char。英文字符占用的是1个字节即1个char。所以如果你要定义中文字符字符数组的话其空间要预留够大。下面定义的“str” 为4个字节的char数组。等号右边“中”是字符常量const char [3]本身“中”字占用2个字节加上字符常量末尾自动添加的0。所以如果等号左边str定义的是 3的数组长度就会提示编译不通过了。为什么中文字符占用两个字节因为一个字节不够表示呗C中中文字符用的是GBK编码的编码方式()。比如上述的存的是-42和-48的原因就是“中”的GBK编码的码值为D6D0。D6也就是用有符号的一个字节表示的 -42。(char 有符号的)D0也就是用有符号的一个字节表示的 -48。查看文字的编码网址汉字字符集编码查询中文字符集编码GB2312、BIG5、GBK、GB18030、Unicodeps那么这个CPP文件首先是一个文本文件选择不同的编码方式其文本的二进制码就是不同的。一般的CPP都是选用utf编码格式的。文本本身的编码格式和C对这个字符的编码格式不是同一个概念。2.wchar_t一个wchar_t占2个字节。16个bit位。一个字符占用一个 wchar_t不管是中文字符还是英文字符。why,因为所有字符都是用utf16编码的下面定义的“str” 为2个字节的wchar_t数组。等号右边L“中”是宽字符常量const wchar_t[2]本身“中”字占用一个wchar_t2个字节加上字符常量末尾自动添加的0。所以如果等号左边str定义的是 2的数组长度就会提示编译不通过了。为什么是20013。因为宽字符用的是unicode而且是utf16中“中”的unicode码点是4E2D而对于一般的字符utf16正好就是直接是码点的值因为都是16位的。wchar_t 是unsigned short16bit的那么就是4E2D就是20013。3.TCHAR是一个宏这个宏的本质类型视情况而定我们说过在 详解windows记事本的4种编码方式 中说过字符集和字符编码方式的概念。那么在C中我们也可以选择使用什么字符集是unicode字符集还是其他字符集这里要特别注意当配置选择使用多字节字符集的时候TCHAR为char注意char对中文字符的编码是GBK2个字节。其他ascii字符是1个字节为什么这叫多字节应该就是一个字符需要用多个TCHAR来编码的意思吧。。当配置选择使用Unicode字符集的时候TCHAR为wchar_twchar_t对中文字符的编码是Unicode。始终是2个字节不管是中文字符还是其他ascii字符。具体的实现方式是通过是否定义了_UNICODE宏对TCHAR进行设置为上述说的不同的类型是char还是wchar_t。ps类似的还有其他的一系列的 A后缀用的就是多字节字符集W后缀用的就是Unicode字符集GetModuleFileName是情况而定是GetModuleFileNameA还是GetModuleFileNameWSetCurrentDirectory是情况而定是SetCurrentDirectoryA还是SetCurrentDirectoryW所以上面的配置只是针对于TCHAR这个宏用的char还是wchar_t。即使当你配置中选择了使用Unicode字符集的时候你还是可以在代码中使用char类型来表示中文其值还是使用GBK的编码方式。当你配置中选择了使用多字节字符集的时候你也还是可以在代码中用wchar_t类型来表示中文时其值是使用utf16的编码方式。char和wchar_t对字符的编码的方式不会随着配置中选择了什么字符集而改变该是什么还是什么。但是对于英文字符来说两者的数值语义是相同的只不过wchar_t的高字节是0wchar_t是占用两个字节的。4.衍生之std::wstring和 std::stringstd::wstring是一个泛型的类其中的类型是wchar_t typedefbasic_stringwchar_twstring;This is an instantiation of the basic_string class template that useswchar_tas thecharacter type, with its default char_traits and allocator typeswstring.length其实就是 std::basic_string::lengthReturns the length ofthe string, in terms of number ofcharacters. 所以这里的字符是wchar的个数如果是string 就是char的个数。This is the number of actual characters that conform the contents of the basic_string, which is not necessarily equal to its storage capacity.Bothbasic_string::sizeandbasic_string::lengthare synonyms and return the same value.4.一些函数1.char 转化为 16进制字符串比如 char* 是utf8编码的字符那输出char*显示肯定是乱码因为char是用GBK编码的。通过下面的函数输出原始的utf8编码的16进制值。注意当16进制的值是一位数的时候需要保留前面的0重点函数sprintf 输出到字符中 格式 %02xstrcat_s 连接字符#include iostream #include stdlib.h #include string.h using namespace std; void main(void) { // 这里没有模拟utf8编码的字符只是举例转为16进制的过程 char str[15] 假如是一堆乱码; char hex_final[100] ; char ch2[3]; // 最后一个str[14] 0 就不翻译为hex了 for (int i 0; i 14; i) { sprintf(ch2,%02x,str[i]); strcat_s(hex_final, ch2); } cout hex_final endl; }3.判断编码是否是utf8的函数bool IsTextUTF8(const std::string str) { char nBytes0;//UFT8可用1-6个字节编码,ASCII用一个字节 unsigned char chr; bool bAllAscii true; //如果全部都是ASCII, 说明不是UTF-8 for(int i0; i str.length();i) { chr str[i]; // 判断是否ASCII编码,如果不是,说明有可能是UTF-8,ASCII用7位编码, // 但用一个字节存,最高位标记为0,o0xxxxxxx if( (chr0x80) ! 0 ) bAllAscii false; if(nBytes0) //如果不是ASCII码,应该是多字节符,计算字节数 { if(chr0x80) { if(chr0xFCchr0xFD) nBytes6; else if(chr0xF8) nBytes5; else if(chr0xF0) nBytes4; else if(chr0xE0) nBytes3; else if(chr0xC0) nBytes2; else{ return false; } nBytes--; } } else //多字节符的非首字节,应为 10xxxxxx { if( (chr0xC0) ! 0x80 ){ return false; } nBytes--; } } if( nBytes 0 ) //违返规则 return false; if( bAllAscii ) //如果全部都是ASCII, 说明不是UTF-8 return false; return true; }但是其实UTF-8 对前 128 个字符0-127的编码与 ASCII 完全一致这是 UTF-8 设计的核心兼容性特征 。2.字符串的UTF-8与GBK(或GB2312)编码转换要么用别人写好的库 iconv要么自己照轮子造轮子 不是很复杂的话可以用这个方法方便如下C/C字符串的UTF-8与GBK(或GB2312)编码转换_devc可以调gbk编码吗_xiaohu_2012的博客-CSDN博客#include iostream #include string #include fstream #include windows.h using namespace std; string Utf8ToGbk(const char *src_str) { int len MultiByteToWideChar(CP_UTF8, 0, src_str, -1, NULL, 0); wchar_t* wszGBK new wchar_t[len 1]; memset(wszGBK, 0, len * 2 2); MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wszGBK, len); len WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); char* szGBK new char[len 1]; memset(szGBK, 0, len 1); WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); string strTemp(szGBK); if (wszGBK) delete[] wszGBK; if (szGBK) delete[] szGBK; return strTemp; } string GbkToUtf8(const char *src_str) { int len MultiByteToWideChar(CP_ACP, 0, src_str, -1, NULL, 0); wchar_t* wstr new wchar_t[len 1]; memset(wstr, 0, len 1); MultiByteToWideChar(CP_ACP, 0, src_str, -1, wstr, len); len WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); char* str new char[len 1]; memset(str, 0, len 1); WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL); string strTemp str; if (wstr) delete[] wstr; if (str) delete[] str; return strTemp; }UE里面自带的字符转换函数// Conversion typedefstypedef TStringConversionTCHAR,ANSICHAR,FANSIToTCHAR_Convert FANSIToTCHAR;typedef TStringConversionANSICHAR,TCHAR,FTCHARToANSI_Convert FTCHARToANSI;typedef TStringConversionANSICHAR,TCHAR,FTCHARToOEM_Convert FTCHARToOEM;typedef TStringConversionANSICHAR,TCHAR,FTCHARToUTF8_Convert FTCHARToUTF8;typedef TStringConversionTCHAR,ANSICHAR,FUTF8ToTCHAR_ConvertFUTF8ToTCHAR;
返回列表