中文编码转换
我的图书馆
中文编码转换
中文编码转换----6种编码30个方向的转换
1.问题提出
&&& 在学编程序时,曾经有人问过“你可以编一个记事本程序吗?”当时很不屑一顾,但是随着学习MFC的深入,了解到记事本程序也并非易事,难点就是四种编码之间的转换。
对于编码,这是一个令初学者头疼的问题,特别是对于编码的转换,更是难以捉摸。笔者为了完成毕业设计中的一个编码转换模块,研究了中文编码和常见的字符集后,决定解决"记事本"程序的编码问题,更进一步完成GB2312、Big5、GBK、Unicode 、Unicode big endian、UTF-8共6种编码之间的任意转换。
2.问题解决&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
(1)编码基础知识
a.了解编码和字符集
这部分内容,我不在赘述,可参见CSDN Ancky的专栏中《各种字符集和编码详解》
b.单字节、双字节、多字节
这部分内容,可参见我先前翻译的博文《C++字符串完全指南--第一部分:win32&字符编码》
c.区域和代码页
这部分内容,可参见博客 & &&
d.中文编码GB2312、GBK、Big5,这部分内容请参见CSDN& lengshine 博客中《GB2312、GBK、Big5汉字编码
》,博客地址:
e.Windows程序的字符编码
这部分内容,可参见博客 中《Windows程序的字符编码》
(2)编码总结
a.六种编码的特点
六种编码的特点如下图所示:
b.编码存储差别
ANSI(在简体中文中默认为GB2312)、Unicode、Unicode big endian 、UTF-8存储存在差别。
以中文"你好"二字为例,他们存贮格式如下图所示:
c.GB2312、Big5、GBK编码的区别
三者中汉字均采用二个字节表示,但是字节表示的值范围有所不同,如下图所示:
(3)编码转换方式
6种编码互相转换,由排列组合知识知道共有30个方向的转换.笔者采用的转换方法,
多字节文件与Unicode文件转换如下图所示:
多字节文件之间转换如下图所示:
(4)编码转换使用的三个函数
a.MultiByteToWideChar
该函数完成多字节字符串向Unicode宽字符串的转换.
函数原型为:
int MultiByteToWideChar(
& UINT CodePage,&&&&&&&& // 代码页
& DWORD dwFlags,&&&&&&&& // 转换标志
& LPCSTR lpMultiByteStr, // 待转换的字符串
& int cbMultiByte,&&&&&& // 待转换字符串的字节数目
& LPWSTR lpWideCharStr,& // 转换后宽字符串的存储空间
& int cchWideChar&&&&&&& // 转换后宽字符串的存储空间大小& 以宽字符大小为单位
b.WideCharToMultiByte
该函数完成Unicode宽字符串到多字节字符串的转换,使用方法具体参见MSDN。
以上两个函数可以完成大部分的字符串转换,可以将其封装成多字节和宽字节之间的转换函数:
[cpp] wchar_t*&Coder::MByteToWChar(UINT&CodePage,LPCSTR&lpcszSrcStr)&&{&&&&&&LPWSTR&lpcwsStrDes=NULL;&&&&&&int&&&len=MultiByteToWideChar(CodePage,0,lpcszSrcStr,-1,NULL,0);&&&&&&lpcwsStrDes=new&wchar_t[len+1];&&&&&&if(!lpcwsStrDes)&&&&&&&&&&return&NULL;&&&&&&memset(lpcwsStrDes,0,sizeof(wchar_t)*(len+1));&&&&&&len=MultiByteToWideChar(CodePage,0,lpcszSrcStr,-1,lpcwsStrDes,len);&&&&&&if(len)&&&&&&&&&&return&lpcwsStrD&&&&&&else&&&&&&{&&&&&&&&&&&&&delete[]&lpcwsStrD&&&&&&&&&&return&NULL;&&&&&&}&&}&&&&char*&Coder::WCharToMByte(UINT&CodePage,LPCWSTR&lpcwszSrcStr)&&{&&&&&&char*&lpszDesStr=NULL;&&&&&&int&len=WideCharToMultiByte(CodePage,0,lpcwszSrcStr,-1,NULL,0,NULL,NULL);&&&&&&lpszDesStr=new&char[len+1];&&&&&&memset(lpszDesStr,0,sizeof(char)*(len+1));&&&&&&if(!lpszDesStr)&&&&&&&&&&return&NULL;&&&&&&len=WideCharToMultiByte(CodePage,0,lpcwszSrcStr,-1,lpszDesStr,len,NULL,NULL);&&&&&&if(len)&&&&&&&&&&return&lpszDesS&&&&&&else&&&&&&{&&&&&&&&&&&&&delete[]&lpszDesS&&&&&&&&&&return&NULL;&&&&&&}&&}&&&c.LCMapString依赖于本地机器的字符转换函数,尤其是中文编码在转换时要依赖于本地机器,直接利用上述a、b中叙述的函数会产生错误,例如直接从GB2312转换到Big5,利用MultiByteToWideChar函数将GB2312转换到Unicode字符串,然后从Unicode字符串利用函数WideCharToMultiByte转换成Big5,将会发生错误,错误的结果如下图所示:
因此中文编码转换时适当使用LCMapString函数,才能完成正确的转换.
[cpp] //简体中文&GB2312&转换成&繁体中文BIG5&&char*&Coder::GB2312ToBIG5(const&char*&szGB2312Str)&&{&&&&&&&&&&&&&&&&&LCID&lcid&=&MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);&&&&&&&&&&int&nLength&=&LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGB2312Str,-1,NULL,0);&&&&&&&&&&char*&pBuffer=new&char[nLength+1];&&&&&&&&&&if(!pBuffer)&&&&&&&&&&&&&&return&NULL;&&&&&&&&&&LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGB2312Str,-1,pBuffer,nLength);&&&&&&&&&&pBuffer[nLength]=0;&&&&&&&&&&wchar_t*&pUnicodeBuff&=&MByteToWChar(CP_GB2312,pBuffer);&&&&&&&&&&char*&pBIG5Buff&=&WCharToMByte(CP_BIG5,pUnicodeBuff);&&&&&&&&&&delete[]&pB&&&&&&&&&&delete[]&pUnicodeB&&&&&&&&&&return&pBIG5B&&}&&&(5)编码实现实现Coder类完成编码转换工作.Coder类的代码清单如下:[cpp] //&Coder.h:&interface&for&the&Coder&class.&&//&&//////////////////////////////////////////////////////////////////////&&&if&!defined(AFX_ENCODING_H__2AC955FB_9F8F__C6CF__INCLUDED_)&define&AFX_ENCODING_H__2AC955FB_9F8F__C6CF__INCLUDED_&&&if&_MSC_VER&&&1000&pragma&once&endif&//&_MSC_VER&&&1000&&//-----------------------------------------------------------------------------------------------&&//程序用途:实现GB2312、big5、GBK、Unicode、Unicode&big&endian、UTF-8六种编码的任意装换&&&&&&//程序作者:湖北师范学院计算机科学与技术学院&&王定桥&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//核心算法:根据不同编码特点向其他编码转换&&//测试结果:在Windows7&VC6.0环境下测试通过&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//制作时间:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//代码版权:代码公开供学习交流使用&&欢迎指正错误&&改善算法&&//-----------------------------------------------------------------------------------------------&&//Windows代码页&&typedef&enum&CodeType&&{&&&&&&CP_GB,&&&&&&CP_BIG5=950,&&&&&&CP_GBK=0&&&&&&&&&//此处特殊处理&CP_GBK仅作一标志&&GBK代码页值尚未查得&&&}CodeP&&//txt文件编码&&typedef&enum&TextCodeType&&{&&&&&&&&&GB2312=0,&&&&&&BIG5=1,&&&&&&GBK=2,&&&&&&UTF8=3,&&&&&&UNICODE=4,&&&&&&UNICODEBIGENDIAN=5,&&&&&&DefaultCodeType=-1&&}TextC&&class&Coder&&&&{&&public:&&&&&&Coder();&&&&&&virtual&~Coder();&&public:&&&&&&//默认一次转换字节大小&&&&&&UINT&&PREDEFINEDSIZE;&&&&&&//指定转换时默认一次转换字节大小&&&&&&void&SetDefaultConvertSize(UINT&nCount);&&&&&&//编码类型转换为字符串&&&&&&CString&&CodeTypeToString(TextCode&tc);&&&&&&//文件转到另一种文件&&&&&&BOOL&&&&&FileToOtherFile(CString&filesourcepath,&CString&filesavepath,TextCode&tcTo,TextCode&&tcCur=DefaultCodeType);&&&&&&//Unicode&和Unicode&big&endian文件之间转换&&&&&&BOOL&&&&&UnicodeEndianFileConvert(CString&filesourcepath,&CString&filesavepath,TextCode&tcTo);&&&&&&//多字节文件之间的转换&&&&&&BOOL&&&&&MBFileToMBFile(CString&filesourcepath,&CString&filesavepath,TextCode&tcTo,TextCode&&tcCur=DefaultCodeType);&&&&&&//Unicode和Unicode&big&endian文件向多字节文件转换&&&&&&BOOL&&&&&UnicodeFileToMBFile(CString&filesourcepath,&CString&filesavepath,TextCode&tcTo);&&&&&&//多字节文件向Unicode和Unicode&big&endian文件转换&&&&&&BOOL&&&&&MBFileToUnicodeFile(CString&filesourcepath,CString&filesavepath,TextCode&tcTo,TextCode&&tcCur=DefaultCodeType);&&&&&&//获取文件编码类型&&&&&&TextCode&GetCodeType(CString&filepath);&&&&&&//繁体中文BIG5&转换成&简体中文&GB2312&&&&&&char*&BIG5ToGB2312(const&char*&szBIG5Str);&&&&&&//简体中文&GB2312&转换成&繁体中文BIG5&&&&&&char*&GB2312ToBIG5(const&char*&szGB2312Str);&&&&&&//简繁中文GBK编码转换成简体中文GB2312&&&&&&char*&GBKToGB2312(const&char&*szGBkStr);&&&&&&//简体中文GB2312编码转换成简繁中文GBK&&&&&&char*&&&&GB2312ToGBK(const&char&*szGB2312Str);&&&&&&//简繁中文GBK转换成繁体中文Big5&&&&&&char*&&&&&GBKToBIG5(const&char&*szGBKStr);&&&&&&//繁体中文BIG5转换到简繁中文GBK&&&&&&char*&&&&&BIG5ToGBK(const&char&*szBIG5Str);&&&&&&//宽字符串向多字节字符串转换&&&&&&char*&&&&&WCharToMByte(UINT&CodePage,LPCWSTR&lpcwszSrcStr);&&&&&&//多字节字符串向宽字符串转换&&&&&&wchar_t*&&MByteToWChar(UINT&CodePage,LPCSTR&lpcszSrcStr);&&protected:&&&&&&//获取编码类型对应的代码页&&&&&&UINT&GetCodePage(TextCode&tccur);&&&&&&//多字节向多字节转换&&&&&&char*&&MByteToMByte(UINT&CodePageCur,UINT&CodePageTo,const&char*&szSrcStr);&&&&&&//Unicode和Unicode&big&endian字符串之间的转换&&&&&&void&&&UnicodeEndianConvert(LPWSTR&&lpwszstr);&&&&&&//文件头常量字节数组&&&&&&const&&static&&&byte&UNICODEBOM[2];&&&&&&const&&static&&&byte&UNICODEBEBOM[2];&&&&&&const&&static&&&byte&UTF8BOM[3];&&&&};&&&endif&//&!defined(AFX_ENCODING_H__2AC955FB_9F8F__C6CF__INCLUDED_)&&[cpp] //&Coder.cpp:&implementation&of&the&Coder&class.&&//&&//////////////////////////////////////////////////////////////////////&&&include&"stdafx.h"&include&"Coder.h"&include&"Encoding.h"&&&ifdef&_DEBUG&undef&THIS_FILE&&static&char&THIS_FILE[]=__FILE__;&define&new&DEBUG_NEW&endif&&&&//////////////////////////////////////////////////////////////////////&&//&Construction/Destruction&&//////////////////////////////////////////////////////////////////////&&//初始化文件头常量&&/*static*/&const&&&&&byte&Coder::UNICODEBOM[2]={0xFF,0xFE};&&/*static*/&const&&&&&byte&Coder::UNICODEBEBOM[2]={0xFE,0xFF};&&/*static*/&const&&&&&byte&Coder::UTF8BOM[3]={0xEF,0xBB,0xBF};&&Coder::Coder()&&{&&&&&PREDEFINEDSIZE=2097152;//默认一次转换字节大小&2M字节&&}&&Coder::~Coder()&&{&&&&&&}&&//繁体中文BIG5&转换成&简体中文&GB2312&&char*&Coder::BIG5ToGB2312(const&char*&szBIG5Str)&&{&&&&&&&&&&&&&&&&&CString&&&&&&&&&&&LCID&lcid&=&MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);&&&&&&&&&&wchar_t*&szUnicodeBuff&=MByteToWChar(CP_BIG5,szBIG5Str);&&&&&&&&&&char*&szGB2312Buff&=WCharToMByte(CP_GB2312,szUnicodeBuff);&&&&&&&&&&int&nLength&=&LCMapString(lcid,LCMAP_SIMPLIFIED_CHINESE,&szGB2312Buff,-1,NULL,0);&&&&&&&&&&char*&pBuffer&=&new&char[nLength&+&1];&&&&&&&&&&if(!pBuffer)&&&&&&&&&&&&return&NULL;&&&&&&&&&&memset(pBuffer,0,sizeof(char)*(nLength+1));&&&&&&&&&&LCMapString(0x0804,LCMAP_SIMPLIFIED_CHINESE,szGB2312Buff,-1,pBuffer,nLength);&&&&&&&&&&delete[]&szUnicodeB&&&&&&&&&&delete[]&szGB2312B&&&&&&&&&&return&pB&&}&&//&GB2312&转&GBK&&char*&Coder::GB2312ToGBK(const&char&*szGB2312Str)&&{&&&&&&&&&int&nStrLen&=&strlen(szGB2312Str);&&&&&&&&&if(!nStrLen)&&&&&&&&&&&&&return&NULL;&&&&&&&&&LCID&wLCID&=&MAKELCID(MAKELANGID(LANG_CHINESE,&SUBLANG_CHINESE_SIMPLIFIED),&SORT_CHINESE_PRC);&&&&&&&&&int&nReturn&=&LCMapString(wLCID,&LCMAP_TRADITIONAL_CHINESE,&szGB2312Str,&nStrLen,&NULL,&0);&&&&&&&&&if(!nReturn)&&&&&&&&&&&&return&NULL;&&&&&&&&&char&*pcBuf&=&new&char[nReturn&+&1];&&&&&&&&&if(!pcBuf)&&&&&&&&&&&&return&NULL;&&&&&&&&&memset(pcBuf,0,sizeof(char)*(nReturn&+&1));&&&&&&&&&wLCID&=&MAKELCID(MAKELANGID(LANG_CHINESE,&SUBLANG_CHINESE_SIMPLIFIED),&SORT_CHINESE_PRC);&&&&&&&&&LCMapString(wLCID,&LCMAP_TRADITIONAL_CHINESE,&szGB2312Str,&nReturn,&pcBuf,&nReturn);&&&&&&&&&return&pcB&&}&&//&GBK&转换成&GB2312&&char*&Coder::GBKToGB2312(const&char&*szGBKStr)&&{&&&&&&int&nStrLen&=&strlen(szGBKStr);&&&&&&if(!nStrLen)&&&&&&&&&&return&NULL;&&&&&&LCID&wLCID&=&MAKELCID(MAKELANGID(LANG_CHINESE,&SUBLANG_CHINESE_SIMPLIFIED),&SORT_CHINESE_BIG5);&&&&&&int&nReturn&=&LCMapString(wLCID,&LCMAP_SIMPLIFIED_CHINESE,&szGBKStr,&nStrLen,&NULL,&0);&&&&&&if(!nReturn)&&&&&&&&&&return&NULL;&&&&&&char&*pcBuf&=&new&char[nReturn&+&1];&&&&&&memset(pcBuf,0,sizeof(char)*(nReturn&+&1));&&&&&&wLCID&=&MAKELCID(MAKELANGID(LANG_CHINESE,&SUBLANG_CHINESE_SIMPLIFIED),&SORT_CHINESE_BIG5);&&&&&&LCMapString(wLCID,&LCMAP_SIMPLIFIED_CHINESE,&szGBKStr,&nReturn,&pcBuf,&nReturn);&&&&&&return&pcB&&}&&//简繁中文GBK转换成繁体中文Big5&&char*&&&Coder::GBKToBIG5(const&char&*szGBKStr)&&{&&&&&&&&&char&*pTemp=NULL;&&&&&&char&*pBuffer=NULL;&&&&&&pTemp=GBKToGB2312(szGBKStr);&&&&&&pBuffer=GB2312ToBIG5(pTemp);&&&&&&delete[]&pT&&&&&&return&pB&&}&&//繁体中文BIG5转换到简繁中文GBK&&char*&&&Coder::BIG5ToGBK(const&char&*szBIG5Str)&&{&&&&&&&&char&*pTemp=NULL;&&&&&&&&char&*pBuffer=NULL;&&&&&&&&pTemp=BIG5ToGB2312(szBIG5Str);&&&&&&&&pBuffer=GB2312ToGBK(pTemp);&&&&&&&&delete[]&pT&&&&&&&&return&pB&&}&&//简体中文&GB2312&转换成&繁体中文BIG5&&char*&Coder::GB2312ToBIG5(const&char*&szGB2312Str)&&{&&&&&&&&&&&&&&&&&LCID&lcid&=&MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);&&&&&&&&&&int&nLength&=&LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGB2312Str,-1,NULL,0);&&&&&&&&&&char*&pBuffer=new&char[nLength+1];&&&&&&&&&&if(!pBuffer)&&&&&&&&&&&&&&return&NULL;&&&&&&&&&&LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGB2312Str,-1,pBuffer,nLength);&&&&&&&&&&pBuffer[nLength]=0;&&&&&&&&&&wchar_t*&pUnicodeBuff&=&MByteToWChar(CP_GB2312,pBuffer);&&&&&&&&&&char*&pBIG5Buff&=&WCharToMByte(CP_BIG5,pUnicodeBuff);&&&&&&&&&&delete[]&pB&&&&&&&&&&delete[]&pUnicodeB&&&&&&&&&&return&pBIG5B&&}&&&//获取文件编码类型&&//Unicode编码文件通过读取文件头判别&&//中文编码通过统计文件编码类别来判别&&判别次数最多为30次&&&&//中文编码的判别存在误差&&TextCode&Coder::GetCodeType(CString&filepath)&&{&&&&&&CFile&&&&&&&byte&&buf[3];//unsigned&char&&&&&&TextCode&&&&&&&if(file.Open(filepath,CFile::modeRead))&&&&&&{&&&&&&&&&&&&&&file.Read(buf,3);&&&&&&&&&&if(buf[0]==UTF8BOM[0]&&&&buf[1]==UTF8BOM[1]&&&&buf[2]==UTF8BOM[2])&&&&&&&&&&&&&&return&UTF8;&&&&&&&&&&else&&&&&&&&&&if(buf[0]==UNICODEBOM[0]&&&buf[1]==UNICODEBOM[1]&)&&&&&&&&&&&&&&return&UNICODE&;&&&&&&&&&&else&&&&&&&&&&if(buf[0]==UNICODEBEBOM[0]&&&buf[1]==UNICODEBEBOM[1]&)&&&&&&&&&&&&&&return&UNICODEBIGENDIAN;&&&&&&&&&&else&&&&&&&&&&{&&&&&&&&&&&&&&&&&int&time=30;&&&&&&&&&&&&&&while(file.Read(buf,2)&&&time&)&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&if&(&(buf[0]&=176&&&&buf[0]&=247)&&&&(buf[1]&=160&&&&buf[1]&=254)&)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&tctemp=GB2312;&&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&&&if&(&(buf[0]&=129&&&&buf[0]&=255)&&&&(&&(&buf[1]&=64&&&&buf[1]&=126)&&||&&(&buf[1]&=161&&&&buf[1]&=254)&)&)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&tctemp=BIG5;&&&&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&&&&&&&if&(&(buf[0]&=129&&&&buf[0]&&=254)&&&&(buf[1]&=64&&&&buf[1]&=254))&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&tctemp=GBK;&&&&&&&&&&&&&&&&&&&time--;&&&&&&&&&&&&&&&&&&file.Seek(100,CFile::current);//跳过一定字节&&利于统计全文&&&&&&&&&&&&&&}&&&&&&&&&&&&&&return&&&&&&&&&&&}&&&&&&}&&&&&&else&&&&&&&&&&return&GB2312;&&}&&//多字节文件转换为UNICODE、UNICODE&big&endian文件&&BOOL&Coder::MBFileToUnicodeFile(CString&filesourcepath,&CString&filesavepath,TextCode&tcTo,TextCode&tcCur)&&{&&&&&TextCode&&&&&&CFile&filesource,;&&&&&char&&&&&*pChSrc=NULL;&&&&&char&&&&&*pChTemp=NULL;&&&&&wchar_t&&*pwChDes=NULL;&&&&&DWORD&&filelength,readlen,&&&&&int&&&&bufferlen,&&&&&UINT&CodeP&&&&&//由于存在误差&&允许用户自定义转换&&&&&if(tcCur!=DefaultCodeType)&&&&&&&&&curtc=tcC&&&&&else&&&&&&&&&curtc=GetCodeType(filesourcepath);&&&&&if(curtc&UTF8&||&tcTo&&UNICODE&||&curtc==tcTo)&&&&&&&&&return&FALSE;&&&&&//源文件打开失败或者源文件无内容&后者保存文件建立失败&&&均返回转换失败&&&&&if(!filesource.Open(filesourcepath,CFile::modeRead)&||&0==(filelength=filesource.GetLength()))&&&&&&&&&return&FALSE;&&&&&if(&!filesave.Open(filesavepath,CFile::modeCreate|CFile::modeWrite))&&&&&&&&&&return&FALSE;&&&&&//预分配内存&&分配失败则转换失败&&&&&if(filelength&PREDEFINEDSIZE)&&&&&&&&&bufferlen=&&&&&else&&&&&&&&&bufferlen=PREDEFINEDSIZE;&&&&&pChSrc=new&char[bufferlen+1];&&&&&if(!pChSrc)&&&&&&&&&&&&&&return&FALSE;&&&&&//根据当前文件类别指定转换代码页&&&&&switch(curtc)&&&&&{&&&&&case&GB2312:&&&&&&&&&CodePage=CP_GB2312;&&&&&&&&&&&&&&case&GBK:&&&&&&&&&CodePage=CP_GB2312;//特殊处理&&&&&&&&&&&&&&case&BIG5:&&&&&&&&&CodePage=CP_BIG5;&&&&&&&&&&&&&&case&UTF8:&&&&&&&&&CodePage=CP_UTF8;&&&&&&&&&&&&&&default:&&&&&&&&&&&&&&&}&&&&&//UTF8文件跳过文件&&&&&if(UTF8==curtc)&&&&&&&&&filesource.Seek(3*sizeof(byte),CFile::begin);&&&&&//写入文件头&&&&&if(UNICODEBIGENDIAN==tcTo)&&&&&&&&&filesave.Write(&UNICODEBEBOM,2*sizeof(byte));&&&&&else&&&&&&&&&filesave.Write(&UNICODEBOM,2*sizeof(byte));&&&&&//读取文件&&分段转换知道结束&&&&&while(filelength&0)&&&&&{&&&&&&&&&memset(pChSrc,0,&sizeof(char)*(bufferlen+1));&&&&&&&&&if(filelength&PREDEFINEDSIZE)&&&&&&&&&&&&&len=PREDEFINEDSIZE;&&&&&&&&&else&&&&&&&&&&&&&len=&&&&&&&&&readlen=filesource.Read(pChSrc,len);&&&&&&&&&if(!readlen)&&&&&&&&&&&&&&&&&&&&&&&//GBK转换为GB2312处理&&&&&&&&&if(GBK==curtc)&&&&&&&&&{&&&&&&&&&&&&&&&&pChTemp=pChS&&&&&&&&&&&&&pChSrc=GBKToGB2312(pChSrc);&&&&&&&&&}&&&&&&&&&pwChDes=MByteToWChar(CodePage,pChSrc);&&&&&&&&&if(pwChDes)&&&&&&&&&{&&&&&&&&&&&&&if(UNICODEBIGENDIAN==tcTo)&&&&&&&&&&&&&&&&&UnicodeEndianConvert(pwChDes);&&&&&&&&&&&&&strlength=wcslen(pwChDes)*2;//这里注意写入文件的长度&&&&&&&&&&&&&filesave.Write(pwChDes,strlength);&&&&&&&&&&&&&filesave.Flush();&&&&&&&&&&&&&filelength-=&&&&&&&&&}&&&&&&&&&else&&&&&&&&&&&&&&&&&&}&&&&&delete[]&pChS&&&&&delete[]&pChT&&&&&delete[]&pwChD&&&&&return&TRUE;&&}&&//&&wchar_t*&Coder::MByteToWChar(UINT&CodePage,LPCSTR&lpcszSrcStr)&&{&&&&&&LPWSTR&lpcwsStrDes=NULL;&&&&&&int&&&len=MultiByteToWideChar(CodePage,0,lpcszSrcStr,-1,NULL,0);&&&&&&lpcwsStrDes=new&wchar_t[len+1];&&&&&&if(!lpcwsStrDes)&&&&&&&&&&return&NULL;&&&&&&memset(lpcwsStrDes,0,sizeof(wchar_t)*(len+1));&&&&&&len=MultiByteToWideChar(CodePage,0,lpcszSrcStr,-1,lpcwsStrDes,len);&&&&&&if(len)&&&&&&&&&&return&lpcwsStrD&&&&&&else&&&&&&{&&&&&&&&&&&&&delete[]&lpcwsStrD&&&&&&&&&&return&NULL;&&&&&&}&&}&&&&char*&Coder::WCharToMByte(UINT&CodePage,LPCWSTR&lpcwszSrcStr)&&{&&&&&&char*&lpszDesStr=NULL;&&&&&&int&len=WideCharToMultiByte(CodePage,0,lpcwszSrcStr,-1,NULL,0,NULL,NULL);&&&&&&lpszDesStr=new&char[len+1];&&&&&&memset(lpszDesStr,0,sizeof(char)*(len+1));&&&&&&if(!lpszDesStr)&&&&&&&&&&return&NULL;&&&&&&len=WideCharToMultiByte(CodePage,0,lpcwszSrcStr,-1,lpszDesStr,len,NULL,NULL);&&&&&&if(len)&&&&&&&&&&return&lpszDesS&&&&&&else&&&&&&{&&&&&&&&&&&&&delete[]&lpszDesS&&&&&&&&&&return&NULL;&&&&&&}&&}&&&//Unicode&和Unicode&big&endian之间字节序的转换&&void&Coder::UnicodeEndianConvert(LPWSTR&lpwszstr)&&{&&&&&&&&&&&wchar_t&&wchtemp[2];&&&&&&&&&long&&&&&&&&&&&&&int&len=wcslen(lpwszstr);&&&&&&&if(!len)&&&&&&&&&&&&&&&&//交换高低字节&直到遇到结束符&&&&&index=0;&&&&&while(&index&len)&&&&&{&&&&&&&&&wchtemp[0]=lpwszstr[index];&&&&&&&&&wchtemp[1]=lpwszstr[index+1];&&&&&&&&&&&&&&&&&&unsigned&char&high,&&&&&&&&&&high&=&(wchtemp[0]&&&0xFF00)&&&8;&&&&&&&&&low&&=&wchtemp[0]&&&0x00FF;&&&&&&&&&wchtemp[0]&=&(&low&&&8)&|&&&&&&&&&&high&=&(wchtemp[1]&&&0xFF00)&&&8;&&&&&&&&&low&&=&wchtemp[1]&&&0x00FF;&&&&&&&&&wchtemp[1]&=&(&low&&&8)&|&&&&&&&&&&&&&&&&&&&lpwszstr[index]=wchtemp[0];&&&&&&&&&lpwszstr[index+1]=wchtemp[1];&&&&&&&&&index+=2;&&&&&}&&}&&//Unicode和Unicode&big&endian文件向多字节文件转换&&BOOL&Coder::UnicodeFileToMBFile(CString&filesourcepath,&CString&filesavepath,TextCode&tcTo)&&{&&&&&&&&&TextCode&&&&&&&CFile&filesource,;&&&&&&char&&&&*pChDes=NULL;&&&&&&char&&&&*pChTemp=NULL;&&&&&&wchar_t&*pwChSrc=NULL;&&&&&&DWORD&&filelength,readlen,&&&&&&int&&&&bufferlen,&&&&&&UINT&CodeP&&&&&&curtc=GetCodeType(filesourcepath);&&&&&&//文件转换类型错误&则转换失败&&&&&&if(curtc&=UTF8&||&&tcTo&UTF8&||&curtc==tcTo)&&&&&&&&&&return&FALSE;&&&&&&//源文件打开失败或者源文件无内容&后者保存文件建立失败&&&均转换失败&&&&&&if(!filesource.Open(filesourcepath,CFile::modeRead)&||&0==(filelength=filesource.GetLength()))&&&&&&&&&&return&FALSE;&&&&&&if(&!filesave.Open(filesavepath,CFile::modeCreate|CFile::modeWrite))&&&&&&&&&&return&FALSE;&&&&&&//预分配内存&&分配失败则转换失败&&&&&&if(filelength&PREDEFINEDSIZE)&&&&&&&&&&bufferlen=&&&&&&else&&&&&&&&&&bufferlen=PREDEFINEDSIZE;&&&&&&pwChSrc=new&wchar_t[(bufferlen/2)+1];&&&&&&if(!pwChSrc)&&&&&&&&&&return&FALSE;&&&&&&//预先决定代码页&&&&&&switch(tcTo)&&&&&&{&&&&&&&&&case&GB2312:&&&&&&&&&&CodePage=CP_GB2312;&&&&&&&&&&&&&&&&case&GBK:&&&&&&&&&&CodePage=CP_GB2312;//特殊处理&&&&&&&&&&&&&&&&case&BIG5:&&&&&&&&&&&CodePage=CP_GB2312;//特殊处理&&&&&&&&&&&&&&&&case&UTF8:&&&&&&&&&&CodePage=CP_UTF8;&&&&&&&&&&&&&&&&default:&&&&&&&&&&&&&&&&&&&&}&&&&&&filesource.Seek(sizeof(wchar_t),CFile::begin);&&&&&&while(filelength&0)&&&&&&{&&&&&&&&&&memset(pwChSrc,0,sizeof(wchar_t)*((bufferlen/2)+1));&&&&&&&&&&if(filelength&PREDEFINEDSIZE)&&&&&&&&&&&&&&len=PREDEFINEDSIZE;&&&&&&&&&&else&&&&&&&&&&&&&&len=&&&&&&&&&&readlen=filesource.Read(pwChSrc,len);&&&&&&&&&&if(!readlen)&&&&&&&&&&&&&&&&&&&&&&&&if(UNICODEBIGENDIAN==curtc)&&&&&&&&&&&&&&UnicodeEndianConvert(pwChSrc);&&&&&&&&&&pChDes=WCharToMByte(CodePage,pwChSrc);&&&&&&&&&&//GBK无法直接转换&&BIG5直接转换会产生错误&&二者均先转到GB2312然后再转到目的类型&&&&&&&&&&if(GBK==tcTo)&&&&&&&&&&{&&&&&&&&&&&&&&pChTemp=pChD&&&&&&&&&&&&&&pChDes=GB2312ToGBK(pChDes);&&&&&&&&&&}&&&&&&&&&&if(BIG5==tcTo)&&&&&&&&&&{&&&&&&&&&&&&&&pChTemp=pChD&&&&&&&&&&&&&&pChDes=GB2312ToBIG5(pChDes);&&&&&&&&&&}&&&&&&&&&&if(pChDes)&&&&&&&&&&{&&&&&&&&&&&&&&&&&strlength=strlen(pChDes);&&&&&&&&&&&&&&filesave.Write(pChDes,strlength);&&&&&&&&&&&&&&filesave.Flush();&&&&&&&&&&&&&&filelength-=&&&&&&&&&&}&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&}&&&&&&delete[]&pChD&&&&&&delete[]&pChT&&&&&&delete[]&pwChS&&&&&&return&TRUE;&&}&&//多字节文件转为多字节文件&&//多字节转为多字节时,一般先转为UNICODE类型,再转换到指定目的类型,实行两次转换&&BOOL&Coder::MBFileToMBFile(CString&filesourcepath,&CString&filesavepath,TextCode&tcTo,TextCode&&tcCur)&&{&&&&&&BOOL&bret=FALSE;&&&&&&TextCode&&&&&&&CFile&filesource,&&&&&&char&&&&*pChDes=NULL;&&&&&&char&&&&*pChSrc=NULL;&&&&&&DWORD&&filelength,readlen,&&&&&&int&&&&bufferlen,&&&&&&UINT&&&CodePageCur,CodePageTo;&&&&&&//由于存在误差&&允许用户自定义转换&&&&&&if(DefaultCodeType!=tcCur)&&&&&&&&&&&curtc=tcC&&&&&&else&&&&&&&&&&curtc=GetCodeType(filesourcepath);&&&&&&//转换类型错误&&则返回转换失败&&&&&&if(curtc&UTF8&||&tcTo&UTF8&||&curtc==tcTo)&&&&&&&&&&return&FALSE;&&&&&&//源文件打开失败或者源文件无内容&后者保存文件建立失败&&&均返回转换失败&&&&&&if(!filesource.Open(filesourcepath,CFile::modeRead)&||&0==(filelength=filesource.GetLength()))&&&&&&&&&&return&FALSE;&&&&&&if(&!filesave.Open(filesavepath,CFile::modeCreate|CFile::modeWrite))&&&&&&&&&&return&FALSE;&&&&&&//预分配内存&&分配失败则转换失败&&&&&&if(filelength&PREDEFINEDSIZE)&&&&&&&&&&bufferlen=&&&&&&else&&&&&&&&&&bufferlen=PREDEFINEDSIZE;&&&&&&pChSrc=new&char[bufferlen+1];&&&&&&if(!pChSrc)&&&&&&&&&&&&&&return&FALSE;&&&&&&if(UTF8==curtc)&&&&&&&&&&filesource.Seek(3*sizeof(byte),CFile::begin);&&&&&&CodePageCur=GetCodePage(curtc);&&&&&&CodePageTo=GetCodePage(tcTo);&&&&&&while(filelength&0)&&&&&&{&&&&&&&&&&&&&memset(pChSrc,0,sizeof(char)*(bufferlen+1));&&&&&&&&&&if(filelength&PREDEFINEDSIZE)&&&&&&&&&&&&&&len=PREDEFINEDSIZE;&&&&&&&&&&else&&&&&&&&&&&&&&len=&&&&&&&&&&readlen=filesource.Read(pChSrc,len);&&&&&&&&&&if(!readlen)&&&&&&&&&&&&&&&&&&&&&&&&pChDes=MByteToMByte(CodePageCur,CodePageTo,pChSrc);&&&&&&&&&&if(pChDes)&&&&&&&&&&{&&&&&&&&&&&&&&&&&strlength=strlen(pChDes);&&&&&&&&&&&&&&filesave.Write(pChDes,strlength);&&&&&&&&&&&&&&filelength-=&&&&&&&&&&}&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&}&&&&&&delete[]&pChS&&&&&&delete[]&pChD&&&&&&return&TRUE;&&}&&//Unicode&和Unicode&big&endian文件之间转换&&BOOL&Coder::UnicodeEndianFileConvert(CString&filesourcepath,&CString&filesavepath,TextCode&tcTo)&&{&&&&&&TextCode&curtc=GetCodeType(filesourcepath);&&&&&&if(curtc!=UNICODE&&&&curtc!=UNICODEBIGENDIAN)&&&&&&&&&&return&FALSE;&&&&&&if(curtc==tcTo)&&&&&&&&&&return&FALSE;&&&&&&CFile&filesource,;&&&&&&wchar_t&*pwChD&&&&&&DWORD&&&&&&&if(!filesource.Open(filesourcepath,CFile::modeRead)&||&!filesave.Open(filesavepath,CFile::modeCreate|CFile::modeWrite))&&&&&&&&&&return&FALSE;&&&&&&length=filesource.GetLength();&&&&&&if(!length)&&&&&&&&&&return&FALSE;&&&&&&pwChDes=new&wchar_t[(length/2)+1];&&&&&&if(!pwChDes)&&&&&&&&&&return&FALSE;&&&&&&memset(pwChDes,0,sizeof(wchar_t)*((length/2)+1));&&&&&&filesource.Read(pwChDes,length);&&&&&&UnicodeEndianConvert(pwChDes);&&&&&&length=wcslen(pwChDes)*2;&&&&&&if(UNICODE==tcTo)&&&&&&&&&&filesave.Write(&UNICODEBOM,2*sizeof(byte));&&&&&&else&&&&&&&&&&filesave.Write(&UNICODEBEBOM,2*sizeof(byte));&&&&&&filesave.Write(pwChDes,length);&&&&&&filesave.Flush();&&&&&&delete[]&pwChD&&&&&&return&TRUE;&&}&&//文件转到另一种文件&&//6种格式文件两两转换&&共计30种转换&&BOOL&Coder::FileToOtherFile(CString&filesourcepath,&CString&filesavepath,&TextCode&tcTo,TextCode&&tcCur)&&{&&&&&&&&&TextCode&&&&&&&BOOL&bret=FALSE;&&&&&&if(DefaultCodeType!=tcCur)&&&&&&&&&&curtc=tcC&&&&&&else&&&&&&&&&&curtc=GetCodeType(filesourcepath);&&&&&&if(curtc==tcTo)&&&&&&&&&&return&FALSE;&&&&&&//UNICODE和UNICODE&big&endian文件之间转换&共2种&&&&&&if(curtc&=UNICODE&&&tcTo&=UNICODE)&&&&&&&&&&&&&&bret=UnicodeEndianFileConvert(filesourcepath,filesavepath,tcTo);&&&&&&else&&&&&&&&&&//多字节文件向&UNICODE和UNICODE&big&endian文件之间转换&共8种&&&&&&&&&&if(curtc&UNICODE&&&&tcTo&=UNICODE)&&&&&&&&&&&&&&bret=MBFileToUnicodeFile(filesourcepath,filesavepath,tcTo,curtc);&&&&&&else&&&&&&&&&&//UNICODE和UNICODE&big&endian文件向多字节文件转换&共8种&&&&&&&&&&if(curtc&=UNICODE&&&&tcTo&UNICODE)&&&&&&&&&&&&&&bret=UnicodeFileToMBFile(filesourcepath,filesavepath,tcTo);&&&&&&else&&&&&&&&&&//多字节文件之间转换&共12种&&&&&&&&&&if(curtc&UNICODE&&&&tcTo&UNICODE)&&&&&&&&&&&&&&bret=MBFileToMBFile(filesourcepath,filesavepath,tcTo,curtc);&&&&&&return&&&}&&//编码类型转换为字符串&&CString&Coder::CodeTypeToString(TextCode&tc)&&{&&&&&&&&CString&&&&&&&&&switch(tc)&&&&&&&&{&&&&&&&&case&GB2312:&&&&&&&&&&&&&strtype=_T("GB2312");&&&&&&&&&&&&&&&&&&&&&case&BIG5:&&&&&&&&&&&&strtype=_T("Big5");&&&&&&&&&&&&&&&&&&&&&case&GBK:&&&&&&&&&&&&strtype=_T("GBK");&&&&&&&&&&&&&&&&&&&&&case&UTF8:&&&&&&&&&&&&strtype=_T("UTF-8");&&&&&&&&&&&&&&&&&&&&&case&UNICODE:&&&&&&&&&&&&strtype=_T("Unicode");&&&&&&&&&&&&&&&&&&&&&case&UNICODEBIGENDIAN:&&&&&&&&&&&&strtype=_T("Unicode&big&endian");&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&return&&&}&&//多字节向多字节转换&&char*&Coder::MByteToMByte(UINT&CodePageCur,&UINT&CodePageTo,&const&char*&szSrcStr)&&{&&&&&&char&&&&*pchDes=NULL;&&&&&&char&&&&*pchTemp=NULL;&&&&&&wchar_t&*pwchtemp=NULL;&&&&&&//三种中文编码之间转换&&&&&&if(CodePageCur!=CP_UTF8&&&&&CodePageTo!=CP_UTF8)&&&&&&{&&&&&&&&&&switch(CodePageCur)&&&&&&&&&&{&&&&&&&&&&&&&&case&CP_GB2312:&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&if(CP_BIG5==CodePageTo)&&&&&&&&&&&&&&&&&&&&&&&&&&pchDes=GB2312ToBIG5(szSrcStr);&&&&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&&&&&&pchDes=GB2312ToGBK(szSrcStr);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&case&CP_BIG5:&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&if(CP_GB2312==CodePageTo)&&&&&&&&&&&&&&&&&&&&&&&&&&pchDes=BIG5ToGB2312(szSrcStr);&&&&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&&&&&&&pchDes=BIG5ToGBK(szSrcStr);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&case&CP_GBK:&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&if(CP_GB2312==CodePageTo)&&&&&&&&&&&&&&&&&&&&&&&&&&pchDes=GBKToGB2312(szSrcStr);&&&&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&&&&&&&pchDes=GBKToBIG5(szSrcStr);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&&&&&else&&&&&&{&&&&//从UTF-8转到其他多字节&&直接转到GB2312&其他形式用GB2312做中间形式&&&&&&&&&&&if(CP_UTF8==CodePageCur)&&&&&&&&&&&{&&&&&&&&&&&&&&&&pwchtemp=MByteToWChar(CodePageCur,szSrcStr);&&&&&&&&&&&&&&if(CP_GB2312==CodePageTo)&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&pchDes=WCharToMByte(CP_GB2312,pwchtemp);&&&&&&&&&&&&&&}&&&&&&&&&&&&&&else&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&pchTemp=WCharToMByte(CP_GB2312,pwchtemp);&&&&&&&&&&&&&&&&&&&if(CP_GBK==CodePageTo)&&&&&&&&&&&&&&&&&&&&&&pchDes=GB2312ToGBK(pchTemp);&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&&&pchDes=GB2312ToBIG5(pchTemp);&&&&&&&&&&&&&&}&&&&&&&&&&&}&&&&&&&&&&&//从其他多字节转到UTF-8&&&&&&&&&&&else&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&if(CP_GBK==CodePageCur)&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&pchTemp=GBKToGB2312(szSrcStr);&&&&&&&&&&&&&&&&&&&&pwchtemp=MByteToWChar(CP_GB2312,pchTemp);&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&pwchtemp=MByteToWChar(CodePageCur,szSrcStr);&&&&&&&&&&&&&&&&pchDes=WCharToMByte(CodePageTo,pwchtemp);&&&&&&&&&&&}&&&&&&}&&&&&&delete[]&pchT&&&&&&delete[]&&&&&&&return&pchD&&}&&//获取编码类型对应的代码页&&UINT&Coder::GetCodePage(TextCode&tccur)&&{&&&&&&&&UINT&CodeP&&&&&&&&switch(tccur)&&&&&&&&{&&&&&&&&case&GB2312:&&&&&&&&&&&&CodePage=CP_GB2312;&&&&&&&&&&&&&&&&&&&&case&BIG5:&&&&&&&&&&&&CodePage=CP_BIG5;&&&&&&&&&&&&&&&&&&&&case&GBK:&&&&&&&&&&&&CodePage=CP_GBK;&&&&&&&&&&&&&&&&&&&&case&UTF8:&&&&&&&&&&&&CodePage=CP_UTF8;&&&&&&&&&&&&&&&&&&&&case&UNICODEBIGENDIAN:&&&&&&&&case&UNICODE:&&&&&&&&&&&&&&&&&&&}&&&&&&&&return&CodeP&&}&&//指定转换时默认一次转换字节大小&&void&Coder::SetDefaultConvertSize(UINT&nCount)&&{&&&&&&&&&&&if(nCount!=0)&&&&&&&&&&PREDEFINEDSIZE=nC&&}&&3.运行效果
在win7 VC 6.0下测试六种编码的转换测试通过,30个方向的转换如下图所示:测试程序运行效果如下图所示:GB2312转换到GBK编码效果如下图所示:
UTF-8转换到Big5编码的效果如下图所示:
本文代码及转码程序下载 :
4.尚未解决的问题&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
(1)LCMapString函数的理解还不完全熟悉,其中参数偏多,理解需要一定基础知识。
(2)为什么记事本程序的转码后存在些乱码,乱码是正确的吗?因为我的程序使用了中间过渡形式,因此没有任何乱码。
(3)是否有更简单和清晰的方式实现编码转换,待进一步研究。
TA的最新馆藏
喜欢该文的人也喜欢