C++:UTF-8、UTF-16、UTF-32之间的编码转换

开发语言:C++ 

功能描述:

Unicode内码转换器。用于UTF-8、UTF-16(UCS2)、UTF-32(UCS4)之间的编码转换。 

下载地址:

UnicodeConverter.zip 

版本历史:

V1.0 2010年03月12日

  • 完成正式版本。

源代码:

UnicodeConverter.h

  1. /* ---------------------------------------------------------- 
  2. 文件名称:UnicodeConverter.h 
  3.  
  4. 作者:秦建辉 
  5.  
  6. MSN:[email protected] 
  7.  
  8. 当前版本:V1.0 
  9.  
  10. 历史版本: 
  11.     V1.0    2010年03月12日 
  12.             完成正式版本。 
  13.  
  14. 功能描述: 
  15.     Unicode内码转换器。用于utf-8、utf-16(UCS2)、utf-32(UCS4)之间的编码转换 
  16.  ------------------------------------------------------------ */  
  17. #pragma once  
  18.   
  19. #include <windows.h>  
  20. #include <stdio.h>  
  21. #include <ostream>  
  22.   
  23. using namespace std;  
  24.   
  25. class CUnicodeConverter  
  26. {  
  27. /* ------------------------------------------------------------- 
  28.                     内码转换 
  29.    ------------------------------------------------------------- */  
  30. public:  
  31.     /* 
  32.     功能:将UCS4编码转换成UTF8编码 
  33.     参数: 
  34.         dwUCS4:要转换的UCS4编码 
  35.         pbUTF8:用于存储转换后的UTF8编码。设为NULL,可以获取长度信息(字节数) 
  36.     返回值: 
  37.           0:无效的UCS4编码 
  38.         1-6:UTF8编码的有效长度 
  39.     */  
  40.     static INT UCS4_To_UTF8( DWORD dwUCS4, BYTE* pbUTF8 );  
  41.   
  42.     /* 
  43.     功能:将UTF8编码转换成UCS4编码 
  44.     参数: 
  45.         pbUTF8:要转换的UTF8编码 
  46.         dwUCS4:存储转换后的UCS4编码 
  47.     返回值: 
  48.           0:参数错误或无效的UTF8编码 
  49.         1-6:UTF8编码的有效长度 
  50.     */  
  51.     static INT UTF8_To_UCS4( const BYTE* pbUTF8, DWORD& dwUCS4 );  
  52.   
  53.     /* 
  54.     功能:将UCS4编码转换成UTF16编码 
  55.     参数: 
  56.         dwUCS4:要转换的UCS4编码 
  57.         pwUTF16:用于存储转换后的UTF16编码。设为NULL,可以获取长度信息(字符数) 
  58.     返回值: 
  59.         0:无效的UCS4编码 
  60.         1:转换成1个UTF16编码 
  61.         2:转换成2个UTF16编码 
  62.     */  
  63.     static INT UCS4_To_UTF16( DWORD dwUCS4, WORD* pwUTF16 );  
  64.   
  65.     /* 
  66.     功能:将UTF16编码转换成UCS4编码 
  67.     参数: 
  68.         pwUTF16:需要转换的UTF16编码 
  69.         dwUCS4:存储转换后的UCS4编码 
  70.     返回值: 
  71.         0:参数错误或无效的UTF16编码 
  72.         1:1个UTF16编码被转换 
  73.         2:2个UTF16编码被转换 
  74.     */  
  75.     static INT UTF16_To_UCS4( const WORD* pwUTF16, DWORD& dwUCS4 );  
  76.   
  77.     /* 
  78.     功能:将UTF8字符串转换成UTF16字符串 
  79.     参数: 
  80.         pbszUTF8Str:需要转换的UTF8字符串 
  81.         pwszUTF16Str:存储转换后的UTF16字符串。设为NULL,可以获取所需长度信息(字符数) 
  82.     返回值: 
  83.          0:转换失败 
  84.         >0:UTF16字符串长度 
  85.     */  
  86.     static INT UTF8Str_To_UTF16Str( const BYTE* pbszUTF8Str, WORD* pwszUTF16Str );  
  87.   
  88.     /* 
  89.     功能:将UTF16字符串转换成UTF8字符串 
  90.     参数: 
  91.         pwszUTF16Str:需要转换的UTF16字符串 
  92.         pbszUTF8Str:存储转换后的UTF8字符串。设为NULL,可以获取所需长度信息(字节数) 
  93.     返回值: 
  94.          0:转换失败 
  95.         >0:UTF8字符串长度(不包括NULL字符) 
  96.     */  
  97.     static INT UTF16Str_To_UTF8Str( const WORD* pwszUTF16Str, BYTE* pbszUTF8Str );  
  98.   
  99. /* ------------------------------------------------------------- 
  100.                     C文件写入操作 
  101.    ------------------------------------------------------------- */  
  102. public:  
  103.     /* 
  104.     功能:向文件中写入UTF8编码 
  105.     返回值: 
  106.         写入的字节数 
  107.     */  
  108.     static UINT Print_UTF8_By_UCS4( FILE* out, DWORD dwUCS4 );  
  109.   
  110.     /* 
  111.     功能:向文件中写入UTF16编码 
  112.     返回值: 
  113.         写入的字节数 
  114.     */  
  115.     static UINT Print_UTF16_By_UCS4( FILE* out, DWORD dwUCS4, BOOL isBigEndian = FALSE );  
  116.   
  117.     /* 
  118.     功能:将UTF16字符串以UTF8编码输出到文件中 
  119.     返回值: 
  120.         写入的字节数 
  121.     */  
  122.     static UINT Print_UTF8Str_By_UTF16Str( FILE* out, const WORD* pwszUTF16Str );  
  123.       
  124.     /* 
  125.     功能:将UTF8字符串以UTF16编码输出到文件中 
  126.     返回值: 
  127.         写入的字节数 
  128.     */  
  129.     static UINT Print_UTF16Str_By_UTF8Str( FILE* out, const BYTE* pbszUTF8Str, BOOL isBigEndian = FALSE );  
  130.   
  131.     /* 
  132.     功能:向文件中输出UTF8编码字节序标记 
  133.     返回值: 
  134.         写入的字节数 
  135.     */  
  136.     static UINT Print_UTF8_BOM( FILE* out );  
  137.   
  138.     /* 
  139.     功能:向文件中输出UTF16编码字节序标记 
  140.     返回值: 
  141.         写入的字节数 
  142.     */  
  143.     static UINT Print_UTF16_BOM( FILE* out, BOOL isBigEndian = FALSE );  
  144.   
  145. /* ------------------------------------------------------------- 
  146.                     C++流输出操作 
  147.    ------------------------------------------------------------- */  
  148. public:  
  149.     /* 
  150.     功能:向流中写入UTF8编码 
  151.     返回值: 
  152.         写入的字节数 
  153.     */  
  154.     static UINT Print_UTF8_By_UCS4( ostream& os, DWORD dwUCS4 );  
  155.   
  156.     /* 
  157.     功能:向流中写入UTF16编码 
  158.     返回值: 
  159.         写入的字节数 
  160.     */  
  161.     static UINT Print_UTF16_By_UCS4( ostream& os, DWORD dwUCS4, BOOL isBigEndian = FALSE );  
  162.   
  163.     /* 
  164.     功能:将UTF16字符串以UTF8编码输出到流中 
  165.     返回值: 
  166.         写入的字节数 
  167.     */  
  168.     static UINT Print_UTF8Str_By_UTF16Str( ostream& os, const WORD* pwszUTF16Str );  
  169.       
  170.     /* 
  171.     功能:将UTF8字符串以UTF16编码输出到流中 
  172.     返回值: 
  173.         写入的字节数 
  174.     */  
  175.     static UINT Print_UTF16Str_By_UTF8Str( ostream& os, const BYTE* pbszUTF8Str, BOOL isBigEndian = FALSE );  
  176.   
  177.     /* 
  178.     功能:向流中输出UTF8编码字节序标记 
  179.     返回值: 
  180.         写入的字节数 
  181.     */  
  182.     static UINT Print_UTF8_BOM( ostream& os );  
  183.   
  184.     /* 
  185.     功能:向流中输出UTF16编码字节序标记 
  186.     返回值: 
  187.         写入的字节数 
  188.     */  
  189.     static UINT Print_UTF16_BOM( ostream& os, BOOL isBigEndian = FALSE );  
  190. };  
  191.   
  192. /* ------------------------------ 
  193.                 END 
  194.    ------------------------------ */  
  

UnicodeConverter.cpp

  1. #include "UnicodeConverter.h"  
  2.   
  3. /* ------------------------------------------------------------- 
  4.                     内码转换 
  5.    ------------------------------------------------------------- */  
  6.   
  7. // 转换UCS4编码到UTF8编码  
  8. INT CUnicodeConverter::UCS4_To_UTF8( DWORD dwUCS4, BYTE* pbUTF8 )  
  9. {  
  10.     const BYTE  abPrefix[] = {0, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};  
  11.     const DWORD adwCodeUp[] = {  
  12.         0x80,           // U+00000000 ~ U+0000007F  
  13.         0x800,          // U+00000080 ~ U+000007FF  
  14.         0x10000,        // U+00000800 ~ U+0000FFFF  
  15.         0x200000,       // U+00010000 ~ U+001FFFFF  
  16.         0x4000000,      // U+00200000 ~ U+03FFFFFF  
  17.         0x80000000      // U+04000000 ~ U+7FFFFFFF  
  18.     };  
  19.   
  20.     INT i, iLen;  
  21.   
  22.     // 根据UCS4编码范围确定对应的UTF-8编码字节数  
  23.     iLen = sizeof(adwCodeUp) / sizeof(DWORD);  
  24.     for( i = 0; i < iLen; i++ )  
  25.     {  
  26.         if( dwUCS4 < adwCodeUp[i] )  
  27.         {  
  28.             break;  
  29.         }  
  30.     }  
  31.   
  32.     if( i == iLen )return 0;    // 无效的UCS4编码  
  33.           
  34.     iLen = i + 1;   // UTF-8编码字节数  
  35.     if( pbUTF8 != NULL )  
  36.     {   // 转换为UTF-8编码  
  37.         for( ; i > 0; i-- )  
  38.         {  
  39.             pbUTF8[i] = static_cast<BYTE>((dwUCS4 & 0x3F) | 0x80);  
  40.             dwUCS4 >>= 6;  
  41.         }  
  42.   
  43.         pbUTF8[0] = static_cast<BYTE>(dwUCS4 | abPrefix[iLen - 1]);  
  44.     }  
  45.   
  46.     return iLen;  
  47. }  
  48.   
  49. // 转换UTF8编码到UCS4编码  
  50. INT CUnicodeConverter::UTF8_To_UCS4( const BYTE* pbUTF8, DWORD& dwUCS4 )  
  51. {  
  52.     INT     i, iLen;  
  53.     BYTE    b;  
  54.   
  55.     if( pbUTF8 == NULL )  
  56.     {   // 参数错误  
  57.         return 0;  
  58.     }  
  59.   
  60.     b = *pbUTF8++;  
  61.     if( b < 0x80 )  
  62.     {  
  63.         dwUCS4 = b;  
  64.         return 1;  
  65.     }  
  66.   
  67.     if( b < 0xC0 || b > 0xFD )  
  68.     {   // 非法UTF8  
  69.         return 0;   
  70.     }  
  71.   
  72.     if( b < 0xE0 )  
  73.     {  
  74.         dwUCS4 = b & 0x1F;  
  75.         iLen = 2;  
  76.     }  
  77.     else if( b < 0xF0 )  
  78.     {  
  79.         dwUCS4 = b & 0x0F;  
  80.         iLen = 3;  
  81.     }  
  82.     else if( b < 0xF8 )  
  83.     {  
  84.         dwUCS4 = b & 7;  
  85.         iLen = 4;  
  86.     }  
  87.     else if( b < 0xFC )  
  88.     {  
  89.         dwUCS4 = b & 3;  
  90.         iLen = 5;  
  91.     }  
  92.     else  
  93.     {  
  94.         dwUCS4 = b & 1;  
  95.         iLen = 6;  
  96.     }  
  97.   
  98.     for( i = 1; i < iLen; i++ )  
  99.     {  
  100.         b = *pbUTF8++;  
  101.         if( b < 0x80 || b > 0xBF )  
  102.         {   // 非法UTF8  
  103.             break;  
  104.         }  
  105.   
  106.         dwUCS4 = (dwUCS4 << 6) + (b & 0x3F);  
  107.     }  
  108.   
  109.     if( i < iLen )  
  110.     {   // 非法UTF8  
  111.         return 0;  
  112.     }  
  113.     else  
  114.     {  
  115.         return iLen;  
  116.     }  
  117. }  
  118.   
  119. // 转换UCS4编码到UCS2编码  
  120. INT CUnicodeConverter::UCS4_To_UTF16( DWORD dwUCS4, WORD* pwUTF16 )  
  121. {  
  122.     if( dwUCS4 <= 0xFFFF )  
  123.     {  
  124.         if( pwUTF16 != NULL )  
  125.         {  
  126.             *pwUTF16 = static_cast<WORD>(dwUCS4);  
  127.         }  
  128.   
  129.         return 1;  
  130.     }  
  131.     else if( dwUCS4 <= 0xEFFFF )  
  132.     {  
  133.         if( pwUTF16 != NULL )  
  134.         {  
  135.             pwUTF16[0] = static_cast<WORD>( 0xD800 + (dwUCS4 >> 10) - 0x40 );   // 高10位  
  136.             pwUTF16[1] = static_cast<WORD>( 0xDC00 + (dwUCS4 & 0x03FF) );     // 低10位  
  137.         }  
  138.   
  139.         return 2;  
  140.     }  
  141.     else  
  142.     {  
  143.         return 0;  
  144.     }  
  145. }  
  146.   
  147. // 转换UCS2编码到UCS4编码  
  148. INT CUnicodeConverter::UTF16_To_UCS4( const WORD* pwUTF16, DWORD& dwUCS4 )  
  149. {  
  150.     WORD    w1, w2;  
  151.   
  152.     if( pwUTF16 == NULL )  
  153.     {   // 参数错误  
  154.         return 0;  
  155.     }  
  156.   
  157.     w1 = pwUTF16[0];  
  158.     if( w1 >= 0xD800 && w1 <= 0xDFFF )  
  159.     {   // 编码在替代区域(Surrogate Area)  
  160.         if( w1 < 0xDC00 )  
  161.         {  
  162.             w2 = pwUTF16[1];  
  163.             if( w2 >= 0xDC00 && w2 <= 0xDFFF )  
  164.             {  
  165.                 dwUCS4 = (w2 & 0x03FF) + (((w1 & 0x03FF) + 0x40) << 10);  
  166.                 return 2;  
  167.             }  
  168.         }  
  169.   
  170.         return 0;   // 非法UTF16编码      
  171.     }  
  172.     else  
  173.     {  
  174.         dwUCS4 = w1;  
  175.         return 1;  
  176.     }  
  177. }  
  178.   
  179. // 转换UTF8字符串到UTF16字符串  
  180. INT CUnicodeConverter::UTF8Str_To_UTF16Str( const BYTE* pbszUTF8Str, WORD* pwszUTF16Str )  
  181. {  
  182.     INT     iNum, iLen;  
  183.     DWORD   dwUCS4;  
  184.   
  185.     if( pbszUTF8Str == NULL )  
  186.     {   // 参数错误  
  187.         return 0;  
  188.     }  
  189.   
  190.     iNum = 0;   // 统计有效字符个数  
  191.     while( *pbszUTF8Str )  
  192.     {   // UTF8编码转换为UCS4编码  
  193.         iLen = UTF8_To_UCS4( pbszUTF8Str, dwUCS4 );  
  194.         if( iLen == 0 )  
  195.         {   // 非法的UTF8编码  
  196.             return 0;  
  197.         }  
  198.   
  199.         pbszUTF8Str += iLen;  
  200.   
  201.         // UCS4编码转换为UTF16编码  
  202.         iLen = UCS4_To_UTF16( dwUCS4, pwszUTF16Str );  
  203.         if( iLen == 0 )  
  204.         {  
  205.             return 0;  
  206.         }  
  207.   
  208.         if( pwszUTF16Str != NULL )  
  209.         {  
  210.             pwszUTF16Str += iLen;  
  211.         }  
  212.           
  213.         iNum += iLen;  
  214.     }  
  215.   
  216.     if( pwszUTF16Str != NULL )  
  217.     {  
  218.         *pwszUTF16Str = 0;  // 写入字符串结束标记  
  219.     }  
  220.   
  221.     return iNum;  
  222. }  
  223.   
  224. // 转换UTF16字符串到UTF8字符串  
  225. INT CUnicodeConverter::UTF16Str_To_UTF8Str( const WORD* pwszUTF16Str, BYTE* pbszUTF8Str )  
  226. {  
  227.     INT     iNum, iLen;  
  228.     DWORD   dwUCS4;  
  229.   
  230.     if( pwszUTF16Str == NULL )  
  231.     {   // 参数错误  
  232.         return 0;  
  233.     }  
  234.   
  235.     iNum = 0;  
  236.     while( *pwszUTF16Str )  
  237.     {   // UTF16编码转换为UCS4编码  
  238.         iLen = UTF16_To_UCS4( pwszUTF16Str, dwUCS4 );  
  239.         if( iLen == 0 )  
  240.         {   // 非法的UTF16编码  
  241.             return 0;     
  242.         }  
  243.           
  244.         pwszUTF16Str += iLen;  
  245.   
  246.         // UCS4编码转换为UTF8编码  
  247.         iLen = UCS4_To_UTF8( dwUCS4, pbszUTF8Str );  
  248.         if( iLen == 0 )  
  249.         {  
  250.             return 0;  
  251.         }  
  252.   
  253.         if( pbszUTF8Str != NULL )  
  254.         {  
  255.             pbszUTF8Str += iLen;  
  256.         }  
  257.           
  258.         iNum += iLen;  
  259.     }  
  260.   
  261.     if( pbszUTF8Str != NULL )  
  262.     {  
  263.         *pbszUTF8Str = 0;   // 写入字符串结束标记  
  264.     }  
  265.   
  266.     return iNum;  
  267. }  
  268.   
  269. /* ------------------------------------------------------------- 
  270.                     C文件写入操作 
  271.    ------------------------------------------------------------- */  
  272.   
  273. // 向文件中输出UTF8编码  
  274. UINT CUnicodeConverter::Print_UTF8_By_UCS4( FILE* out, DWORD dwUCS4 )  
  275. {  
  276.     INT     iLen;  
  277.     BYTE    abUTF8[8];  
  278.   
  279.     if( out == NULL )  
  280.     {  
  281.         return 0;  
  282.     }  
  283.   
  284.     iLen = UCS4_To_UTF8( dwUCS4, abUTF8 );  
  285.     if( iLen == 0 )return 0;  
  286.   
  287.     fwrite( abUTF8, 1, iLen, out );  
  288.   
  289.     return iLen;  
  290. }  
  291.   
  292. // 向文件中输出UTF16编码  
  293. UINT CUnicodeConverter::Print_UTF16_By_UCS4( FILE* out, DWORD dwUCS4, BOOL isBigEndian )  
  294. {  
  295.     INT     i, iLen;  
  296.     WORD    wCode, awUTF16[2];  
  297.   
  298.     if( out == NULL )  
  299.     {  
  300.         return 0;  
  301.     }  
  302.   
  303.     iLen = UCS4_To_UTF16( dwUCS4, awUTF16 );  
  304.     if( iLen == 0 )return 0;  
  305.   
  306.     for( i = 0; i < iLen; i++ )  
  307.     {  
  308.         wCode = awUTF16[i];  
  309.         if( isBigEndian )  
  310.         {  
  311.             fputc( wCode >> 8, out ); // 输出高位  
  312.             fputc( wCode & 0xFF, out ); // 输出低位  
  313.         }  
  314.         else  
  315.         {  
  316.             fputc( wCode & 0xFF, out ); // 输出低位  
  317.             fputc( wCode >> 8, out ); // 输出高位  
  318.         }  
  319.     }  
  320.   
  321.     return (iLen << 1);  
  322. }  

你可能感兴趣的:(utf-8)