一网打尽中文编码转换---6种编码30个方向的转换

一网打尽中文编码转换——6编码30个方向的转换

1.问题提出

    在学编程序时,曾经有人问过“你可以编一个记事本程序吗?”当时很不屑一顾,但是随着学习MFC的深入,了解到记事本程序也并非易事,难点就是四种编码之间的转换。

对于编码,这是一个令初学者头疼的问题,特别是对于编码的转换,更是难以捉摸。笔者为了完成毕业设计中的一个编码转换模块,研究了中文编码和常见的字符集后,决定解决"记事本"程序的编码问题,更进一步完成GB2312、Big5、GBK、Unicode 、Unicode big endian、UTF-8共6种编码之间的任意转换。

2.问题解决                                                                                                                                                                                         

(1)编码基础知识

a.了解编码和字符集

这部分内容,我不在赘述,可参见CSDN Ancky的专栏中《各种字符集和编码详解》

博客地址:http://blog.csdn.net/ancky/article/details/2034809

b.单字节、双字节、多字节

这部分内容,可参见我先前翻译的博文《C++字符串完全指南--第一部分:win32 字符编码》

博客地址:http://blog.csdn.net/ziyuanxiazai123/article/details/7482360

c.区域和代码页

这部分内容,可参见博客      http://hi.baidu.com/tzpwater/blog/item/bd4abb0b60bff1db3ac7636a.html

d.中文编码GB2312、GBK、Big5,这部分内容请参见CSDN  lengshine 博客中《GB2312、GBK、Big5汉字编码
》,博客地址:http://blog.csdn.net/lengshine/article/details/5470545

e.Windows程序的字符编码

这部分内容,可参见博客http://blog.sina.com.cn/s/blog_4e3197f20100a6z2.html 中《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] view plaincopyprint?
  1. wchar_t* Coder::MByteToWChar(UINT CodePage,LPCSTR lpcszSrcStr)  
  2. {  
  3.     LPWSTR lpcwsStrDes=NULL;  
  4.     int   len=MultiByteToWideChar(CodePage,0,lpcszSrcStr,-1,NULL,0);  
  5.     lpcwsStrDes=new wchar_t[len+1];  
  6.     if(!lpcwsStrDes)  
  7.         return NULL;  
  8.     memset(lpcwsStrDes,0,sizeof(wchar_t)*(len+1));  
  9.     len=MultiByteToWideChar(CodePage,0,lpcszSrcStr,-1,lpcwsStrDes,len);  
  10.     if(len)  
  11.         return lpcwsStrDes;  
  12.     else  
  13.     {     
  14.         delete[] lpcwsStrDes;  
  15.         return NULL;  
  16.     }  
  17. }  
  18.   
  19. char* Coder::WCharToMByte(UINT CodePage,LPCWSTR lpcwszSrcStr)  
  20. {  
  21.     char* lpszDesStr=NULL;  
  22.     int len=WideCharToMultiByte(CodePage,0,lpcwszSrcStr,-1,NULL,0,NULL,NULL);  
  23.     lpszDesStr=new char[len+1];  
  24.     memset(lpszDesStr,0,sizeof(char)*(len+1));  
  25.     if(!lpszDesStr)  
  26.         return NULL;  
  27.     len=WideCharToMultiByte(CodePage,0,lpcwszSrcStr,-1,lpszDesStr,len,NULL,NULL);  
  28.     if(len)  
  29.         return lpszDesStr;  
  30.     else  
  31.     {     
  32.         delete[] lpszDesStr;  
  33.         return NULL;  
  34.     }  
  35. }   
c.LCMapString 依赖于本地机器的字符转换函数,尤其是中文编码在转换时要依赖于本地机器, 直接利用上述a、b中叙述的函数会产生错误,例如直接从GB2312转换到Big5,利用
MultiByteToWideChar函数将GB2312转换到Unicode字符串,然后从Unicode字符串利用函数
WideCharToMultiByte转换成Big5,将会发生错误,错误的结果如下图所示:
因此中文编码转换时适当使用LCMapString函数,才能完成正确的转换.
例如:
[cpp] view plaincopyprint?
  1. //简体中文 GB2312 转换成 繁体中文BIG5  
  2. char* Coder::GB2312ToBIG5(const char* szGB2312Str)  
  3. {         
  4.         LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);  
  5.         int nLength = LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGB2312Str,-1,NULL,0);  
  6.         char* pBuffer=new char[nLength+1];  
  7.         if(!pBuffer)  
  8.             return NULL;  
  9.         LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGB2312Str,-1,pBuffer,nLength);  
  10.         pBuffer[nLength]=0;  
  11.         wchar_t* pUnicodeBuff = MByteToWChar(CP_GB2312,pBuffer);  
  12.         char* pBIG5Buff = WCharToMByte(CP_BIG5,pUnicodeBuff);  
  13.         delete[] pBuffer;  
  14.         delete[] pUnicodeBuff;  
  15.         return pBIG5Buff;  
  16. }   
(5)编码实现 实现Coder类完成编码转换工作. Coder类的代码清单如下:
[cpp] view plaincopyprint?
  1. // Coder.h: interface for the Coder class.  
  2. //  
  3. //  
  4.   
  5. #if !defined(AFX_ENCODING_H__2AC955FB_9F8F_4871_9B77_C6C65730507F__INCLUDED_)  
  6. #define AFX_ENCODING_H__2AC955FB_9F8F_4871_9B77_C6C65730507F__INCLUDED_  
  7.   
  8. #if _MSC_VER > 1000  
  9. #pragma once  
  10. #endif // _MSC_VER > 1000  
  11. //-----------------------------------------------------------------------------------------------  
  12. //程序用途:实现GB2312、big5、GBK、Unicode、Unicode big endian、UTF-8六种编码的任意装换      
  13. //程序作者:湖北师范学院计算机科学与技术学院  王定桥                                   
  14. //核心算法:根据不同编码特点向其他编码转换  
  15. //测试结果:在Windows7 VC6.0环境下测试通过                                                       
  16. //制作时间:2012-04-24                                               
  17. //代码版权:代码公开供学习交流使用  欢迎指正错误  改善算法  
  18. //-----------------------------------------------------------------------------------------------  
  19. //Windows代码页  
  20. typedef enum CodeType  
  21. {  
  22.     CP_GB2312=936,  
  23.     CP_BIG5=950,  
  24.     CP_GBK=0  
  25. }CodePages;  
  26. //txt文件编码  
  27. typedef enum TextCodeType  
  28. {     
  29.     GB2312=0,  
  30.     BIG5=1,  
  31.     GBK=2,  
  32.     UTF8=3,  
  33.     UNICODE=4,  
  34.     UNICODEBIGENDIAN=5,  
  35.     DefaultCodeType=-1  
  36. }TextCode;  
  37. class Coder    
  38. {  
  39. public:  
  40.     Coder();  
  41.     virtual ~Coder();  
  42. public:  
  43.     //默认一次转换字节大小  
  44.     UINT  PREDEFINEDSIZE;  
  45.     //指定转换时默认一次转换字节大小  
  46.     void SetDefaultConvertSize(UINT nCount);  
  47.     //编码类型转换为字符串  
  48.     CString  CodeTypeToString(TextCode tc);  
  49.     //文件转到另一种文件  
  50.     BOOL     FileToOtherFile(CString filesourcepath, CString filesavepath,TextCode tcTo,TextCode  tcCur=DefaultCodeType);  
  51.     //Unicode 和Unicode big endian文件之间转换  
  52.     BOOL     UnicodeEndianFileConvert(CString filesourcepath, CString filesavepath,TextCode tcTo);  
  53.     //多字节文件之间的转换  
  54.     BOOL     MBFileToMBFile(CString filesourcepath, CString filesavepath,TextCode tcTo,TextCode  tcCur=DefaultCodeType);  
  55.     //Unicode和Unicode big endian文件向多字节文件转换  
  56.     BOOL     UnicodeFileToMBFile(CString filesourcepath, CString filesavepath,TextCode tcTo);  
  57.     //多字节文件向Unicode和Unicode big endian文件转换  
  58.     BOOL     MBFileToUnicodeFile(CString filesourcepath,CString filesavepath,TextCode tcTo,TextCode  tcCur=DefaultCodeType);  
  59.     //获取文件编码类型  
  60.     TextCode GetCodeType(CString filepath);  
  61.     //繁体中文BIG5 转换成 简体中文 GB2312  
  62.     char* BIG5ToGB2312(const char* szBIG5Str);  
  63.     //简体中文 GB2312 转换成 繁体中文BIG5  
  64.     char* GB2312ToBIG5(const char* szGB2312Str);  
  65.     //简繁中文GBK编码转换成简体中文GB2312  
  66.     char* GBKToGB2312(const char *szGBkStr);  
  67.     //简体中文GB2312编码转换成简繁中文GBK  
  68.     char*    GB2312ToGBK(const char *szGB2312Str);  
  69.     //简繁中文GBK转换成繁体中文Big5  
  70.     char*     GBKToBIG5(const char *szGBKStr);  
  71.     //繁体中文BIG5转换到简繁中文GBK  
  72.     char*     BIG5ToGBK(const char *szBIG5Str);  
  73.     //宽字符串向多字节字符串转换  
  74.     char*     WCharToMByte(UINT CodePage,LPCWSTR lpcwszSrcStr);  
  75.     //多字节字符串向宽字符串转换  
  76.     wchar_t*  MByteToWChar(UINT CodePage,LPCSTR lpcszSrcStr);  
  77. protected:  
  78.     //获取编码类型对应的代码页  
  79.     UINT GetCodePage(TextCode tccur);  
  80.     //多字节向多字节转换  
  81.     char*  MByteToMByte(UINT CodePageCur,UINT CodePageTo,const char* szSrcStr);  
  82.     //Unicode和Unicode big endian字符串之间的转换  
  83.     void   UnicodeEndianConvert(LPWSTR  lpwszstr);  
  84.     //文件头常量字节数组  
  85.     const  static   byte UNICODEBOM[2];  
  86.     const  static   byte UNICODEBEBOM[2];  
  87.     const  static   byte UTF8BOM[3];  
  88.   };  
  89.   
  90. #endif // !defined(AFX_ENCODING_H__2AC955FB_9F8F_4871_9B77_C6C65730507F__INCLUDED_)  
[cpp] view plaincopyprint?
  1. // Coder.cpp: implementation of the Coder class.  
  2. //  
  3. //  
  4.   
  5. #include "stdafx.h"  
  6. #include "Coder.h"  
  7. #include "Encoding.h"  
  8.   
  9. #ifdef _DEBUG  
  10. #undef THIS_FILE  
  11. static char THIS_FILE[]=__FILE__;  
  12. #define new DEBUG_NEW  
  13. #endif  
  14.   
  15. //  
  16. // Construction/Destruction  
  17. //  
  18. //初始化文件头常量  
  19. /*static*/ const     byte Coder::UNICODEBOM[2]={0xFF,0xFE};  
  20. /*static*/ const     byte Coder::UNICODEBEBOM[2]={0xFE,0xFF};  
  21. /*static*/ const     byte Coder::UTF8BOM[3]={0xEF,0xBB,0xBF};  
  22. Coder::Coder()  
  23. {  
  24.    PREDEFINEDSIZE=2097152;//默认一次转换字节大小 2M字节  
  25. }  
  26. Coder::~Coder()  
  27. {  
  28.     
  29. }  
  30. //繁体中文BIG5 转换成 简体中文 GB2312  
  31. char* Coder::BIG5ToGB2312(const char* szBIG5Str)  
  32. {         
  33.         CString msg;  
  34.         LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);  
  35.         wchar_t* szUnicodeBuff =MByteToWChar(CP_BIG5,szBIG5Str);  
  36.         char* szGB2312Buff =WCharToMByte(CP_GB2312,szUnicodeBuff);  
  37.         int nLength = LCMapString(lcid,LCMAP_SIMPLIFIED_CHINESE, szGB2312Buff,-1,NULL,0);  
  38.         char* pBuffer = new char[nLength + 1];  
  39.         if(!pBuffer)  
  40.           return NULL;  
  41.         memset(pBuffer,0,sizeof(char)*(nLength+1));  
  42.         LCMapString(0x0804,LCMAP_SIMPLIFIED_CHINESE,szGB2312Buff,-1,pBuffer,nLength);  
  43.         delete[] szUnicodeBuff;  
  44.         delete[] szGB2312Buff;  
  45.         return pBuffer;  
  46. }  
  47. // GB2312 转 GBK  
  48. char* Coder::GB2312ToGBK(const char *szGB2312Str)  
  49. {  
  50.        int nStrLen = strlen(szGB2312Str);  
  51.        if(!nStrLen)  
  52.            return NULL;  
  53.        LCID wLCID = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_PRC);  
  54.        int nReturn = LCMapString(wLCID, LCMAP_TRADITIONAL_CHINESE, szGB2312Str, nStrLen, NULL, 0);  
  55.        if(!nReturn)  
  56.           return NULL;  
  57.        char *pcBuf = new char[nReturn + 1];  
  58.        if(!pcBuf)  
  59.           return NULL;  
  60.        memset(pcBuf,0,sizeof(char)*(nReturn + 1));  
  61.        wLCID = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_PRC);  
  62.        LCMapString(wLCID, LCMAP_TRADITIONAL_CHINESE, szGB2312Str, nReturn, pcBuf, nReturn);  
  63.        return pcBuf;  
  64. }  
  65. // GBK 转换成 GB2312  
  66. char* Coder::GBKToGB2312(const char *szGBKStr)  
  67. {  
  68.     int nStrLen = strlen(szGBKStr);  
  69.     if(!nStrLen)  
  70.         return NULL;  
  71.     LCID wLCID = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_BIG5);  
  72.     int nReturn = LCMapString(wLCID, LCMAP_SIMPLIFIED_CHINESE, szGBKStr, nStrLen, NULL, 0);  
  73.     if(!nReturn)  
  74.         return NULL;  
  75.     char *pcBuf = new char[nReturn + 1];  
  76.     memset(pcBuf,0,sizeof(char)*(nReturn + 1));  
  77.     wLCID = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_BIG5);  
  78.     LCMapString(wLCID, LCMAP_SIMPLIFIED_CHINESE, szGBKStr, nReturn, pcBuf, nReturn);  
  79.     return pcBuf;  
  80. }  
  81. //简繁中文GBK转换成繁体中文Big5  
  82. char*   Coder::GBKToBIG5(const char *szGBKStr)  
  83. {     
  84.     char *pTemp=NULL;  
  85.     char *pBuffer=NULL;  
  86.     pTemp=GBKToGB2312(szGBKStr);  
  87.     pBuffer=GB2312ToBIG5(pTemp);  
  88.     delete[] pTemp;  
  89.     return pBuffer;  
  90. }  
  91. //繁体中文BIG5转换到简繁中文GBK  
  92. char*   Coder::BIG5ToGBK(const char *szBIG5Str)  
  93. {  
  94.       char *pTemp=NULL;  
  95.       char *pBuffer=NULL;  
  96.       pTemp=BIG5ToGB2312(szBIG5Str);  
  97.       pBuffer=GB2312ToGBK(pTemp);  
  98.       delete[] pTemp;  
  99.       return pBuffer;  
  100. }  
  101. //简体中文 GB2312 转换成 繁体中文BIG5  
  102. char* Coder::GB2312ToBIG5(const char* szGB2312Str)  
  103. {         
  104.         LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);  
  105.         int nLength = LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGB2312Str,-1,NULL,0);  
  106.         char* pBuffer=new char[nLength+1];  
  107.         if(!pBuffer)  
  108.             return NULL;  
  109.         LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGB2312Str,-1,pBuffer,nLength);  
  110.         pBuffer[nLength]=0;  
  111.         wchar_t* pUnicodeBuff = MByteToWChar(CP_GB2312,pBuffer);  
  112.         char* pBIG5Buff = WCharToMByte(CP_BIG5,pUnicodeBuff);  
  113.         delete[] pBuffer;  
  114.         delete[] pUnicodeBuff;  
  115.         return pBIG5Buff;  
  116. }   
  117. //获取文件编码类型  
  118. //Unicode编码文件通过读取文件头判别  
  119. //中文编码通过统计文件编码类别来判别  判别次数最多为30次    
  120. //中文编码的判别存在误差  
  121. TextCode Coder::GetCodeType(CString filepath)  
  122. {  
  123.     CFile file;  
  124.     byte  buf[3];//unsigned char  
  125.     TextCode tctemp;  
  126.     if(file.Open(filepath,CFile::modeRead))  
  127.     {      
  128.         file.Read(buf,3);  
  129.         if(buf[0]==UTF8BOM[0] && buf[1]==UTF8BOM[1] && buf[2]==UTF8BOM[2])  
  130.             return UTF8;  
  131.         else  
  132.         if(buf[0]==UNICODEBOM[0] &&buf[1]==UNICODEBOM[1] )  
  133.             return UNICODE ;  
  134.         else  
  135.         if(buf[0]==UNICODEBEBOM[0] &&buf[1]==UNICODEBEBOM[1] )  
  136.             return UNICODEBIGENDIAN;  
  137.         else  
  138.         {     
  139.             int time=30;  
  140.             while(file.Read(buf,2) &&time )  
  141.             {     
  142.                 if ( (buf[0]>=176 && buf[0]<=247) && (buf[1]>=160 && buf[1]<=254) )  
  143.                             tctemp=GB2312;    
  144.                 else  
  145.                     if ( (buf[0]>=129 && buf[0]<=255) && (  ( buf[1]>=64 && buf[1]<=126)  ||  ( buf[1]>=161 && buf[1]<=254) ) )  
  146.                             tctemp=BIG5;  
  147.                     else  
  148.                         if ( (buf[0]>=129 && buf[0] <=254) && (buf[1]>=64 && buf[1]<=254))  
  149.                             tctemp=GBK;   
  150.                 time--;  
  151.                 file.Seek(100,CFile::current);//跳过一定字节  利于统计全文  
  152.             }  
  153.             return tctemp;  
  154.         }  
  155.     }  
  156.     else  
  157.         return GB2312;  
  158. }  
  159. //多字节文件转换为UNICODE、UNICODE big endian文件  
  160. BOOL Coder::MBFileToUnicodeFile(CString filesourcepath, CString filesavepath,TextCode tcTo,TextCode tcCur)  
  161. {  
  162.    TextCode curtc;  
  163.    CFile filesource,filesave;;  
  164.    char     *pChSrc=NULL;  
  165.    char     *pChTemp=NULL;  
  166.    wchar_t  *pwChDes=NULL;  
  167.    DWORD  filelength,readlen,len;  
  168.    int    bufferlen,strlength;  
  169.    UINT CodePage;  
  170.    //由于存在误差  允许用户自定义转换  
  171.    if(tcCur!=DefaultCodeType)  
  172.        curtc=tcCur;  
  173.    else  
  174.        curtc=GetCodeType(filesourcepath);  
  175.    if(curtc>UTF8 || tcTo< UNICODE || curtc==tcTo)  
  176.        return FALSE;  
  177.    //源文件打开失败或者源文件无内容 后者保存文件建立失败   均返回转换失败  
  178.    if(!filesource.Open(filesourcepath,CFile::modeRead) || 0==(filelength=filesource.GetLength()))  
  179.        return FALSE;  
  180.    if( !filesave.Open(filesavepath,CFile::modeCreate|CFile::modeWrite))  
  181.         return FALSE;  
  182.    //预分配内存  分配失败则转换失败  
  183.    if(filelength<PREDEFINEDSIZE)  
  184.        bufferlen=filelength;  
  185.    else  
  186.        bufferlen=PREDEFINEDSIZE;  
  187.    pChSrc=new char[bufferlen+1];  
  188.    if(!pChSrc)  
  189.             return FALSE;  
  190.    //根据当前文件类别指定转换代码页  
  191.    switch(curtc)  
  192.    {  
  193.    case GB2312:  
  194.        CodePage=CP_GB2312;  
  195.        break;  
  196.    case GBK:  
  197.        CodePage=CP_GB2312;//特殊处理  
  198.        break;  
  199.    case BIG5:  
  200.        CodePage=CP_BIG5;  
  201.        break;  
  202.    case UTF8:  
  203.        CodePage=CP_UTF8;  
  204.        break;  
  205.    default:  
  206.        break;  
  207.     }  
  208.    //UTF8文件跳过文件  
  209.    if(UTF8==curtc)  
  210.        filesource.Seek(3*sizeof(byte),CFile::begin);  
  211.    //写入文件头  
  212.    if(UNICODEBIGENDIAN==tcTo)  
  213.        filesave.Write(&UNICODEBEBOM,2*sizeof(byte));  
  214.    else  
  215.        filesave.Write(&UNICODEBOM,2*sizeof(byte));  
  216.    //读取文件  分段转换知道结束  
  217.    while(filelength>0)  
  218.    {  
  219.        memset(pChSrc,0, sizeof(char)*(bufferlen+1));  
  220.        if(filelength>PREDEFINEDSIZE)  
  221.            len=PREDEFINEDSIZE;  
  222.        else  
  223.            len=filelength;  
  224.        readlen=filesource.Read(pChSrc,len);  
  225.        if(!readlen)  
  226.             break;  
  227.        //GBK转换为GB2312处理  
  228.        if(GBK==curtc)  
  229.        {     
  230.            pChTemp=pChSrc;  
  231.            pChSrc=GBKToGB2312(pChSrc);  
  232.        }  
  233.        pwChDes=MByteToWChar(CodePage,pChSrc);  
  234.        if(pwChDes)  
  235.        {  
  236.            if(UNICODEBIGENDIAN==tcTo)  
  237.                UnicodeEndianConvert(pwChDes);  
  238.            strlength=wcslen(pwChDes)*2;//这里注意写入文件的长度  
  239.            filesave.Write(pwChDes,strlength);  
  240.            filesave.Flush();  
  241.            filelength-=readlen;  
  242.        }  
  243.        else  
  244.            break;  
  245.    }  
  246.    delete[] pChSrc;  
  247.    delete[] pChTemp;  
  248.    delete[] pwChDes;  
  249.    return TRUE;  
  250. }  
  251. //  
  252. wchar_t* Coder::MByteToWChar(UINT CodePage,LPCSTR lpcszSrcStr)  
  253. {  
  254.     LPWSTR lpcwsStrDes=NULL;  
  255.     int   len=MultiByteToWideChar(CodePage,0,lpcszSrcStr,-1,NULL,0);  
  256.     lpcwsStrDes=new wchar_t[len+1];  
  257.     if(!lpcwsStrDes)  
  258.         return NULL;  
  259.     memset(lpcwsStrDes,0,sizeof(wchar_t)*(len+1));  
  260.     len=MultiByteToWideChar(CodePage,0,lpcszSrcStr,-1,lpcwsStrDes,len);  
  261.     if(len)  
  262.         return lpcwsStrDes;  
  263.     else  
  264.     {     
  265.         delete[] lpcwsStrDes;  
  266.         return NULL;  
  267.     }  
  268. }  
  269.   
  270. char* Coder::WCharToMByte(UINT CodePage,LPCWSTR lpcwszSrcStr)  
  271. {  
  272.     char* lpszDesStr=NULL;  
  273.     int len=WideCharToMultiByte(CodePage,0,lpcwszSrcStr,-1,NULL,0,NULL,NULL);  
  274.     lpszDesStr=new char[len+1];  
  275.     memset(lpszDesStr,0,sizeof(char)*(len+1));  
  276.     if(!lpszDesStr)  
  277.         return NULL;  
  278.     len=WideCharToMultiByte(CodePage,0,lpcwszSrcStr,-1,lpszDesStr,len,NULL,NULL);  
  279.     if(len)  
  280.         return lpszDesStr;  
  281.     else  
  282.     {     
  283.         delete[] lpszDesStr;  
  284.         return NULL;  
  285.     }  
  286. }   
  287. //Unicode 和Unicode big endian之间字节序的转换  
  288. void Coder::UnicodeEndianConvert(LPWSTR lpwszstr)  
  289. {      
  290.      wchar_t  wchtemp[2];    
  291.      long     index;   
  292.      int len=wcslen(lpwszstr);  
  293.      if(!len)  
  294.          return;  
  295.    //交换高低字节 直到遇到结束符  
  296.    index=0;  
  297.    while( index<len)  
  298.    {  
  299.        wchtemp[0]=lpwszstr[index];  
  300.        wchtemp[1]=lpwszstr[index+1];  
  301.          
  302.        unsigned char high, low;  
  303.        high = (wchtemp[0] & 0xFF00) >>8;  
  304.        low  = wchtemp[0] & 0x00FF;  
  305.        wchtemp[0] = ( low <<8) | high;  
  306.        high = (wchtemp[1] & 0xFF00) >>8;  
  307.        low  = wchtemp[1] & 0x00FF;  
  308.        wchtemp[1] = ( low <<8) | high;  
  309.          
  310.        lpwszstr[index]=wchtemp[0];  
  311.        lpwszstr[index+1]=wchtemp[1];  
  312.        index+=2;  
  313.    }  
  314. }  
  315. //Unicode和Unicode big endian文件向多字节文件转换  
  316. BOOL Coder::UnicodeFileToMBFile(CString filesourcepath, CString filesavepath,TextCode tcTo)  
  317. {     
  318.     TextCode curtc;  
  319.     CFile filesource,filesave;;  
  320.     char    *pChDes=NULL;  
  321.     char    *pChTemp=NULL;  
  322.     wchar_t *pwChSrc=NULL;  
  323.     DWORD  filelength,readlen,len;  
  324.     int    bufferlen,strlength;  
  325.     UINT CodePage;  
  326.     curtc=GetCodeType(filesourcepath);  
  327.     //文件转换类型错误 则转换失败  
  328.     if(curtc<=UTF8 ||  tcTo>UTF8 || curtc==tcTo)  
  329.         return FALSE;  
  330.     //源文件打开失败或者源文件无内容 后者保存文件建立失败   均转换失败  
  331.     if(!filesource.Open(filesourcepath,CFile::modeRead) || 0==(filelength=filesource.GetLength()))  
  332.         return FALSE;  
  333.     if( !filesave.Open(filesavepath,CFile::modeCreate|CFile::modeWrite))  
  334.         return FALSE;  
  335.     //预分配内存  分配失败则转换失败  
  336.     if(filelength<PREDEFINEDSIZE)  
  337.         bufferlen=filelength;  
  338.     else  
  339.         bufferlen=PREDEFINEDSIZE;  
  340.     pwChSrc=new wchar_t[(bufferlen/2)+1];  
  341.     if(!pwChSrc)  
  342.         return FALSE;  
  343.     //预先决定代码页  
  344.     switch(tcTo)  
  345.     {     
  346.     case GB2312:  
  347.         CodePage=CP_GB2312;  
  348.         break;  
  349.     case GBK:  
  350.         CodePage=CP_GB2312;//特殊处理  
  351.         break;  
  352.     case BIG5:   
  353.         CodePage=CP_GB2312;//特殊处理  
  354.         break;  
  355.     case UTF8:  
  356.         CodePage=CP_UTF8;  
  357.         break;  
  358.     default:  
  359.         break;  
  360.         }  
  361.     filesource.Seek(sizeof(wchar_t),CFile::begin);  
  362.     while(filelength>0)  
  363.     {  
  364.         memset(pwChSrc,0,sizeof(wchar_t)*((bufferlen/2)+1));  
  365.         if(filelength>PREDEFINEDSIZE)  
  366.             len=PREDEFINEDSIZE;  
  367.         else  
  368.             len=filelength;  
  369.         readlen=filesource.Read(pwChSrc,len);  
  370.         if(!readlen)  
  371.             break;  
  372.         if(UNICODEBIGENDIAN==curtc)  
  373.             UnicodeEndianConvert(pwChSrc);  
  374.         pChDes=WCharToMByte(CodePage,pwChSrc);  
  375.         //GBK无法直接转换  BIG5直接转换会产生错误  二者均先转到GB2312然后再转到目的类型  
  376.         if(GBK==tcTo)  
  377.         {  
  378.             pChTemp=pChDes;  
  379.             pChDes=GB2312ToGBK(pChDes);  
  380.         }  
  381.         if(BIG5==tcTo)  
  382.         {  
  383.             pChTemp=pChDes;  
  384.             pChDes=GB2312ToBIG5(pChDes);  
  385.         }  
  386.         if(pChDes)  
  387.         {     
  388.             strlength=strlen(pChDes);  
  389.             filesave.Write(pChDes,strlength);  
  390.             filesave.Flush();  
  391.             filelength-=readlen;  
  392.         }  
  393.         else  
  394.             break;  
  395.     }  
  396.     delete[] pChDes;  
  397.     delete[] pChTemp;  
  398.     delete[] pwChSrc;  
  399.     return TRUE;  
  400. }  
  401. //多字节文件转为多字节文件  
  402. //多字节转为多字节时,一般先转为UNICODE类型,再转换到指定目的类型,实行两次转换  
  403. BOOL Coder::MBFileToMBFile(CString filesourcepath, CString filesavepath,TextCode tcTo,TextCode  tcCur)  
  404. {  
  405.     BOOL bret=FALSE;  
  406.     TextCode curtc;  
  407.     CFile filesource,filesave;  
  408.     char    *pChDes=NULL;  
  409.     char    *pChSrc=NULL;  
  410.     DWORD  filelength,readlen,len;  
  411.     int    bufferlen,strlength;  
  412.     UINT   CodePageCur,CodePageTo;  
  413.     //由于存在误差  允许用户自定义转换  
  414.     if(DefaultCodeType!=tcCur)  
  415.          curtc=tcCur;  
  416.     else  
  417.         curtc=GetCodeType(filesourcepath);  
  418.     //转换类型错误  则返回转换失败  
  419.     if(curtc>UTF8 || tcTo>UTF8 || curtc==tcTo)  
  420.         return FALSE;  
  421.     //源文件打开失败或者源文件无内容 后者保存文件建立失败   均返回转换失败  
  422.     if(!filesource.Open(filesourcepath,CFile::modeRead) || 0==(filelength=filesource.GetLength()))  
  423.         return FALSE;  
  424.     if( !filesave.Open(filesavepath,CFile::modeCreate|CFile::modeWrite))  
  425.         return FALSE;  
  426.     //预分配内存  分配失败则转换失败  
  427.     if(filelength<PREDEFINEDSIZE)  
  428.         bufferlen=filelength;  
  429.     else  
  430.         bufferlen=PREDEFINEDSIZE;  
  431.     pChSrc=new char[bufferlen+1];  
  432.     if(!pChSrc)  
  433.             return FALSE;  
  434.     if(UTF8==curtc)  
  435.         filesource.Seek(3*sizeof(byte),CFile::begin);  
  436.     CodePageCur=GetCodePage(curtc);  
  437.     CodePageTo=GetCodePage(tcTo);  
  438.     while(filelength>0)  
  439.     {     
  440.         memset(pChSrc,0,sizeof(char)*(bufferlen+1));  
  441.         if(filelength>PREDEFINEDSIZE)  
  442.             len=PREDEFINEDSIZE;  
  443.         else  
  444.             len=filelength;  
  445.         readlen=filesource.Read(pChSrc,len);  
  446.         if(!readlen)  
  447.             break;  
  448.         pChDes=MByteToMByte(CodePageCur,CodePageTo,pChSrc);  
  449.         if(pChDes)  
  450.         {     
  451.             strlength=strlen(pChDes);  
  452.             filesave.Write(pChDes,strlength);  
  453.             filelength-=readlen;  
  454.         }  
  455.         else  
  456.             break;  
  457.     }  
  458.     delete[] pChSrc;  
  459.     delete[] pChDes;  
  460.     return TRUE;  
  461. }  
  462. //Unicode 和Unicode big endian文件之间转换  
  463. BOOL Coder::UnicodeEndianFileConvert(CString filesourcepath, CString filesavepath,TextCode tcTo)  
  464. {  
  465.     TextCode curtc=GetCodeType(filesourcepath);  
  466.     if(curtc!=UNICODE && curtc!=UNICODEBIGENDIAN)  
  467.         return FALSE;  
  468.     if(curtc==tcTo)  
  469.         return FALSE;  
  470.     CFile filesource,filesave;;  
  471.     wchar_t *pwChDes;  
  472.     DWORD length;  
  473.     if(!filesource.Open(filesourcepath,CFile::modeRead) || !filesave.Open(filesavepath,CFile::modeCreate|CFile::modeWrite))  
  474.         return FALSE;  
  475.     length=filesource.GetLength();  
  476.     if(!length)  
  477.         return FALSE;  
  478.     pwChDes=new wchar_t[(length/2)+1];  
  479.     if(!pwChDes)  
  480.         return FALSE;  
  481.     memset(pwChDes,0,sizeof(wchar_t)*((length/2)+1));  
  482.     filesource.Read(pwChDes,length);  
  483.     UnicodeEndianConvert(pwChDes);  
  484.     length=wcslen(pwChDes)*2;  
  485.     if(UNICODE==tcTo)  
  486.         filesave.Write(&UNICODEBOM,2*sizeof(byte));  
  487.     else  
  488.         filesave.Write(&UNICODEBEBOM,2*sizeof(byte));  
  489.     filesave.Write(pwChDes,length);  
  490.     filesave.Flush();  
  491.     delete[] pwChDes;  
  492.     return TRUE;  
  493. }  
  494. //文件转到另一种文件  
  495. //6种格式文件两两转换  共计30种转换  
  496. BOOL Coder::FileToOtherFile(CString filesourcepath, CString filesavepath, TextCode tcTo,TextCode  tcCur)  
  497. {     
  498.     TextCode curtc;  
  499.     BOOL bret=FALSE;  
  500.     if(DefaultCodeType!=tcCur)  
  501.         curtc=tcCur;  
  502.     else  
  503.         curtc=GetCodeType(filesourcepath);  
  504.     if(curtc==tcTo)  
  505.         return FALSE;  
  506.     //UNICODE和UNICODE big endian文件之间转换 共2种  
  507.     if(curtc>=UNICODE&& tcTo>=UNICODE)  
  508.             bret=UnicodeEndianFileConvert(filesourcepath,filesavepath,tcTo);  
  509.     else  
  510.         //多字节文件向 UNICODE和UNICODE big endian文件之间转换 共8种  
  511.         if(curtc<UNICODE && tcTo>=UNICODE)  
  512.             bret=MBFileToUnicodeFile(filesourcepath,filesavepath,tcTo,curtc);  
  513.     else  
  514.         //UNICODE和UNICODE big endian文件向多字节文件转换 共8种  
  515.         if(curtc>=UNICODE && tcTo<UNICODE)  
  516.             bret=UnicodeFileToMBFile(filesourcepath,filesavepath,tcTo);  
  517.     else  
  518.         //多字节文件之间转换 共12种  
  519.         if(curtc<UNICODE && tcTo<UNICODE)  
  520.             bret=MBFileToMBFile(filesourcepath,filesavepath,tcTo,curtc);  
  521.     return bret;  
  522. }  
  523. //编码类型转换为字符串  
  524. CString Coder::CodeTypeToString(TextCode tc)  
  525. {  
  526.       CString strtype;  
  527.       switch(tc)  
  528.       {  
  529.       case GB2312:  
  530.            strtype=_T("GB2312");  
  531.            break;  
  532.       case BIG5:  
  533.           strtype=_T("Big5");  
  534.            break;  
  535.       case GBK:  
  536.           strtype=_T("GBK");  
  537.            break;  
  538.       case UTF8:  
  539.           strtype=_T("UTF-8");  
  540.            break;  
  541.       case UNICODE:  
  542.           strtype=_T("Unicode");  
  543.            break;  
  544.       case UNICODEBIGENDIAN:  
  545.           strtype=_T("Unicode big endian");  
  546.            break;  
  547.       }  
  548.       return strtype;  
  549. }  
  550. //多字节向多字节转换  
  551. char* Coder::MByteToMByte(UINT CodePageCur, UINT CodePageTo, const char* szSrcStr)  
  552. {  
  553.     char    *pchDes=NULL;  
  554.     char    *pchTemp=NULL;  
  555.     wchar_t *pwchtemp=NULL;  
  556.     //三种中文编码之间转换  
  557.     if(CodePageCur!=CP_UTF8  && CodePageTo!=CP_UTF8)  
  558.     {  
  559.         switch(CodePageCur)  
  560.         {  
  561.             case CP_GB2312:  
  562.                 {  
  563.                     if(CP_BIG5==CodePageTo)   
  564.                        pchDes=GB2312ToBIG5(szSrcStr);  
  565.                     else  
  566.                        pchDes=GB2312ToGBK(szSrcStr);  
  567.                     break;  
  568.                 }  
  569.             case CP_BIG5:  
  570.                 {     
  571.                     if(CP_GB2312==CodePageTo)  
  572.                         pchDes=BIG5ToGB2312(szSrcStr);  
  573.                     else  
  574.                         pchDes=BIG5ToGBK(szSrcStr);  
  575.                     break;  
  576.                 }  
  577.             case CP_GBK:  
  578.                 {     
  579.                     if(CP_GB2312==CodePageTo)  
  580.                         pchDes=GBKToGB2312(szSrcStr);  
  581.                     else  
  582.                         pchDes=GBKToBIG5(szSrcStr);  
  583.                     break;  
  584.                 }  
  585.         }  
  586.     }  
  587.     else  
  588.     {    //从UTF-8转到其他多字节  直接转到GB2312 其他形式用GB2312做中间形式  
  589.          if(CP_UTF8==CodePageCur)  
  590.          {    
  591.             pwchtemp=MByteToWChar(CodePageCur,szSrcStr);  
  592.             if(CP_GB2312==CodePageTo)  
  593.             {  
  594.                 pchDes=WCharToMByte(CP_GB2312,pwchtemp);  
  595.             }  
  596.             else  
  597.             {      
  598.                 pchTemp=WCharToMByte(CP_GB2312,pwchtemp);  
  599.                  if(CP_GBK==CodePageTo)  
  600.                     pchDes=GB2312ToGBK(pchTemp);  
  601.                  else  
  602.                     pchDes=GB2312ToBIG5(pchTemp);  
  603.             }  
  604.          }  
  605.          //从其他多字节转到UTF-8  
  606.          else   
  607.          {      
  608.               if(CP_GBK==CodePageCur)  
  609.               {     
  610.   
  611.                   pchTemp=GBKToGB2312(szSrcStr);  
  612.                   pwchtemp=MByteToWChar(CP_GB2312,pchTemp);  
  613.               }  
  614.               else  
  615.                 pwchtemp=MByteToWChar(CodePageCur,szSrcStr);  
  616.               pchDes=WCharToMByte(CodePageTo,pwchtemp);  
  617.          }  
  618.     }  
  619.     delete[] pchTemp;  
  620.     delete[] pwchtemp;  
  621.     return pchDes;  
  622. }  
  623. //获取编码类型对应的代码页  
  624. UINT Coder::GetCodePage(TextCode tccur)  
  625. {  
  626.       UINT CodePage;  
  627.       switch(tccur)  
  628.       {  
  629.       case GB2312:  
  630.           CodePage=CP_GB2312;  
  631.           break;  
  632.       case BIG5:  
  633.           CodePage=CP_BIG5;  
  634.           break;  
  635.       case GBK:  
  636.           CodePage=CP_GBK;  
  637.           break;  
  638.       case UTF8:  
  639.           CodePage=CP_UTF8;  
  640.           break;  
  641.       case UNICODEBIGENDIAN:  
  642.       case UNICODE:  
  643.            break;  
  644.     }  
  645.       return CodePage;  
  646. }  
  647. //指定转换时默认一次转换字节大小  
  648. void Coder::SetDefaultConvertSize(UINT nCount)  
  649. {      
  650.      if(nCount!=0)  
  651.         PREDEFINEDSIZE=nCount;  
  652. }  
3.运行效果 在win7 VC 6.0下测试六种编码的转换测试通过,30个方向的转换如下图所示:

测试程序运行效果如下图所示:


GB2312转换到GBK编码效果如下图所示:



UTF-8转换到Big5编码的效果如下图所示:


本文代码及转码程序下载 :http://download.csdn.net/user/ziyuanxiazai123

4.尚未解决的问题                                                                                                                                                                             

(1)LCMapString函数的理解还不完全熟悉,其中参数偏多,理解需要一定基础知识。

(2)为什么记事本程序的转码后存在些乱码,乱码是正确的吗?因为我的程序使用了中间过渡形式,因此没有任何乱码。

(3)是否有更简单和清晰的方式实现编码转换,待进一步研究。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/452225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十万服务器秒级管控 腾讯云如何将AIOps用于日常管理?

AIOps&#xff0c;是指基于算法的 IT运维&#xff08;Algorithmic IT Operations&#xff09;&#xff0c;由 Gartner定义的新类别&#xff0c;源自业界之前所说的 ITOA&#xff08;IT Operations and Analytics&#xff09;。我们已经到达了这样的一个时代&#xff0c;数据科学…

ssm(springMVC + spring+MyBatis) 小例

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 整体环境参见本人另一文&#xff1a;http://blog.csdn.net/jiangyu1013/article/details/51983360 此工程访问入口为index.jsp页面. 工…

学成在线--13.RabbitMQ工作模式

文章目录一.Work queues二.Publish/subscribe1.工作模式2.代码1&#xff09;生产者2&#xff09;消费者3.测试4.思考三.Routing1.工作模式2.代码1&#xff09;生产者2&#xff09;消费者3.测试4.思考四.Topics1.工作模式2.代码1&#xff09;生产者2&#xff09;消费者3.测试4.思…

《C++字符串完全指南——第一部分:win32 字符编码》

《C字符串完全指南--第一部分:win32 字符编码》 原作者:Michael Dun 译 者:Dingqiao Wang 引言 毫无疑问&#xff0c;你肯定见过像TCHAR, std::string, BSTR等等这类字符串类型.也包括一些以_tcs开头的奇怪的宏。也许你正盯着屏幕"哇哇"的发愁&#xff0c;然…

学成在线--14.使用RabbitMQ完成页面发布

文章目录一.技术方案二.页面发布——消费方1.需求分析2.创建Cms Client工程1&#xff09;创建maven工程2&#xff09;配置文件3&#xff09;启动类3.RabbitmqConfig配置类4.定义消息格式5.PageDao1&#xff09;使用CmsPageRepository 查询页面信息2&#xff09;使用CmsSiteRepo…

Log4J日志配置详解

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、Log4j简介 Log4j有三个主要的组件&#xff1a;Loggers(记录器)&#xff0c;Appenders (输出源)和Layouts(布局)。这里可简单理解为日…

中文编码杂谈

编码问题的例子 在windows自带的notepad&#xff08;记事本&#xff09;程序中输入“联通”两个字&#xff0c;保存后再次打开&#xff0c;会发现“联通”不见了&#xff0c;代之以“”的乱码。这是windows平台上典型的中文编码问题。即文件保存的时候是按照ANSI编码&#xff…

easyUI 日期控件修改...

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 个人觉得easyUI挺好用的。 它的中文文档地址&#xff1a; http://www.zi-han.net/case/easyui/ 日期本来效果是这样的&#xff1a; 改…

面向对象分析的三个模型与5个层次

在面向对象分析中&#xff0c;主要由对象模型、动态模型和功能模型组成。对象模型是最基本、最重要、最核心的。 面向对象建模得到的模型包含系统的3个要素&#xff0c;即静态结构(对象模型)、交互次序(动态模型)和数据变换(功能模型)。解决的问题不同&#xff0c;这3个子模型…

学成在线--15.课程计划查询

文章目录一.需求分析二.页面原型1.tree组件介绍2.webstorm配置jsx三.API接口1.数据模型2.自定义模型类3.接口定义四.sql语句五.服务器端1.Dao1&#xff09;Mapper接口2&#xff09;Mapper映射文件2.Service3.Controller4.测试六.前端1.Api方法2.Api调用1&#xff09;定义查询课…

团队作业-项目答辩

1. 王书磊 1600802063 http://www.cnblogs.com/wsl-1117/ 刘令斌 1600802017 http://www.cnblogs.com/liulingbin/ 许浩然 1600802066 https://www.cnblogs.com/xuhaoran1/ 成明龙 1600802038 http://www.cnblogs.com/CMLCML/ 2这是我们的效果图. 3.&#xff08;1&#xff09;修…

Java构造和解析Json数据的两种方法详解一

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 在www.json.org上公布了很多JAVA下的json构造和解析工具&#xff0c;其中org.json和json-lib比较简单&#xff0c;两者使用上差不多但还是…

JsRender 前端渲染模板常用API学习

JsRender 常用API 1. $.templates() $.templates()方法是用来注册或编译模板的&#xff0c;使用的情况有以下几种。 把html字符串编译编译成模板获取使用script标签声明的模板&#xff0c;并返回一个模板对象把html字符串或者在script标签中声明的模板注册成命名模板获取之前就…

状态图

状态图(Statechart Diagram)是描述一个实体基于事件反应的动态行为&#xff0c;显示了该实体如何根据当前所处的状态对不同的事件做出反应。通常我们创建一个UML状态图是为了以下的研究目的&#xff1a;研究类、角色、子系统、或组件的复杂行为。

我身边的手机应用开发者

手机应用火了&#xff0c;我身边的一位朋友(A君)也投身到开发者行列&#xff0c;不过他还算聪明并没有辞掉工作专做手机应用软件开发。 其原因在于他们领导打算做一款自己的应用软件&#xff0c;正当A君愁到底是做IOS平台还是Android平台的时候&#xff0c;领导说&#xff1a;…

学成在线--16.添加课程计划

文章目录一.需求分析二.API接口三.后端1.Dao2.Service3.Controller4.测试四.前端1.页面原型说明1&#xff09;添加按钮2&#xff09;视图部分3&#xff09;在数据模型中添加如下变量4&#xff09;定义表单提交方法和重置方法2.Api调用1&#xff09;定义 api方法2&#xff09;调…

理解 maven 的核心概念

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 本文以类图的方式&#xff0c;介绍 maven 核心的 12 个概念及相互之间的关系。 Table of Contents 1 maven管理的目标&#xff1a;工程…

C#关键字的使用

params object[] 用于函数多参数的定义public static void Write(string format, params object[] arg);explicit 关键字用于声明必须使用强制转换来调用的用户定义的类型转换运算符。 例如&#xff0c;在下面的示例中&#xff0c;此运算符将名为 Fahrenheit 的类转换为名为 Ce…

maven 中 pom.xml 配置文件标签说明,dependencyManagement和dependencies区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 参考&#xff1a;http://zhaoshijie.iteye.com/blog/2094478http://blog.csdn.net/cpf2016/article/details/45674377 还有一篇转载文章…

学成在线--17.我的课程

文章目录一.需求分析二.API接口三.PageHelper1.PageHelper介绍2.添加依赖3.配置pageHelper四.Dao1.mapper 接口2.mapper.xml映射文件3.测试Dao五.Service六.Controller七.前端1.创建course_list.vue2.路由3.定义API方法4.前端视图course_list.vue详解1&#xff09;API调用--在视…