`
java-mans
  • 浏览: 11414148 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

开发语言:C++

功能描述:

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

下载地址:

UnicodeConverter.zip

版本历史:

V1.02010年03月12日

  • 完成正式版本。

源代码:

UnicodeConverter.h

  1. /*----------------------------------------------------------
  2. 文件名称:UnicodeConverter.h
  3. 作者:秦建辉
  4. MSN:splashcn@msn.com
  5. 当前版本:V1.0
  6. 历史版本:
  7. V1.02010年03月12日
  8. 完成正式版本。
  9. 功能描述:
  10. Unicode内码转换器。用于utf-8、utf-16(UCS2)、utf-32(UCS4)之间的编码转换
  11. ------------------------------------------------------------*/
  12. #pragmaonce
  13. #include<windows.h>
  14. #include<stdio.h>
  15. #include<ostream>
  16. usingnamespacestd;
  17. classCUnicodeConverter
  18. {
  19. /*-------------------------------------------------------------
  20. 内码转换
  21. -------------------------------------------------------------*/
  22. public:
  23. /*
  24. 功能:将UCS4编码转换成UTF8编码
  25. 参数:
  26. dwUCS4:要转换的UCS4编码
  27. pbUTF8:用于存储转换后的UTF8编码。设为NULL,可以获取长度信息(字节数)
  28. 返回值:
  29. 0:无效的UCS4编码
  30. 1-6:UTF8编码的有效长度
  31. */
  32. staticINTUCS4_To_UTF8(DWORDdwUCS4,BYTE*pbUTF8);
  33. /*
  34. 功能:将UTF8编码转换成UCS4编码
  35. 参数:
  36. pbUTF8:要转换的UTF8编码
  37. dwUCS4:存储转换后的UCS4编码
  38. 返回值:
  39. 0:参数错误或无效的UTF8编码
  40. 1-6:UTF8编码的有效长度
  41. */
  42. staticINTUTF8_To_UCS4(constBYTE*pbUTF8,DWORD&dwUCS4);
  43. /*
  44. 功能:将UCS4编码转换成UTF16编码
  45. 参数:
  46. dwUCS4:要转换的UCS4编码
  47. pwUTF16:用于存储转换后的UTF16编码。设为NULL,可以获取长度信息(字符数)
  48. 返回值:
  49. 0:无效的UCS4编码
  50. 1:转换成1个UTF16编码
  51. 2:转换成2个UTF16编码
  52. */
  53. staticINTUCS4_To_UTF16(DWORDdwUCS4,WORD*pwUTF16);
  54. /*
  55. 功能:将UTF16编码转换成UCS4编码
  56. 参数:
  57. pwUTF16:需要转换的UTF16编码
  58. dwUCS4:存储转换后的UCS4编码
  59. 返回值:
  60. 0:参数错误或无效的UTF16编码
  61. 1:1个UTF16编码被转换
  62. 2:2个UTF16编码被转换
  63. */
  64. staticINTUTF16_To_UCS4(constWORD*pwUTF16,DWORD&dwUCS4);
  65. /*
  66. 功能:将UTF8字符串转换成UTF16字符串
  67. 参数:
  68. pbszUTF8Str:需要转换的UTF8字符串
  69. pwszUTF16Str:存储转换后的UTF16字符串。设为NULL,可以获取所需长度信息(字符数)
  70. 返回值:
  71. 0:转换失败
  72. >0:UTF16字符串长度
  73. */
  74. staticINTUTF8Str_To_UTF16Str(constBYTE*pbszUTF8Str,WORD*pwszUTF16Str);
  75. /*
  76. 功能:将UTF16字符串转换成UTF8字符串
  77. 参数:
  78. pwszUTF16Str:需要转换的UTF16字符串
  79. pbszUTF8Str:存储转换后的UTF8字符串。设为NULL,可以获取所需长度信息(字节数)
  80. 返回值:
  81. 0:转换失败
  82. >0:UTF8字符串长度(不包括NULL字符)
  83. */
  84. staticINTUTF16Str_To_UTF8Str(constWORD*pwszUTF16Str,BYTE*pbszUTF8Str);
  85. /*-------------------------------------------------------------
  86. C文件写入操作
  87. -------------------------------------------------------------*/
  88. public:
  89. /*
  90. 功能:向文件中写入UTF8编码
  91. 返回值:
  92. 写入的字节数
  93. */
  94. staticUINTPrint_UTF8_By_UCS4(FILE*out,DWORDdwUCS4);
  95. /*
  96. 功能:向文件中写入UTF16编码
  97. 返回值:
  98. 写入的字节数
  99. */
  100. staticUINTPrint_UTF16_By_UCS4(FILE*out,DWORDdwUCS4,BOOLisBigEndian=FALSE);
  101. /*
  102. 功能:将UTF16字符串以UTF8编码输出到文件中
  103. 返回值:
  104. 写入的字节数
  105. */
  106. staticUINTPrint_UTF8Str_By_UTF16Str(FILE*out,constWORD*pwszUTF16Str);
  107. /*
  108. 功能:将UTF8字符串以UTF16编码输出到文件中
  109. 返回值:
  110. 写入的字节数
  111. */
  112. staticUINTPrint_UTF16Str_By_UTF8Str(FILE*out,constBYTE*pbszUTF8Str,BOOLisBigEndian=FALSE);
  113. /*
  114. 功能:向文件中输出UTF8编码字节序标记
  115. 返回值:
  116. 写入的字节数
  117. */
  118. staticUINTPrint_UTF8_BOM(FILE*out);
  119. /*
  120. 功能:向文件中输出UTF16编码字节序标记
  121. 返回值:
  122. 写入的字节数
  123. */
  124. staticUINTPrint_UTF16_BOM(FILE*out,BOOLisBigEndian=FALSE);
  125. /*-------------------------------------------------------------
  126. C++流输出操作
  127. -------------------------------------------------------------*/
  128. public:
  129. /*
  130. 功能:向流中写入UTF8编码
  131. 返回值:
  132. 写入的字节数
  133. */
  134. staticUINTPrint_UTF8_By_UCS4(ostream&os,DWORDdwUCS4);
  135. /*
  136. 功能:向流中写入UTF16编码
  137. 返回值:
  138. 写入的字节数
  139. */
  140. staticUINTPrint_UTF16_By_UCS4(ostream&os,DWORDdwUCS4,BOOLisBigEndian=FALSE);
  141. /*
  142. 功能:将UTF16字符串以UTF8编码输出到流中
  143. 返回值:
  144. 写入的字节数
  145. */
  146. staticUINTPrint_UTF8Str_By_UTF16Str(ostream&os,constWORD*pwszUTF16Str);
  147. /*
  148. 功能:将UTF8字符串以UTF16编码输出到流中
  149. 返回值:
  150. 写入的字节数
  151. */
  152. staticUINTPrint_UTF16Str_By_UTF8Str(ostream&os,constBYTE*pbszUTF8Str,BOOLisBigEndian=FALSE);
  153. /*
  154. 功能:向流中输出UTF8编码字节序标记
  155. 返回值:
  156. 写入的字节数
  157. */
  158. staticUINTPrint_UTF8_BOM(ostream&os);
  159. /*
  160. 功能:向流中输出UTF16编码字节序标记
  161. 返回值:
  162. 写入的字节数
  163. */
  164. staticUINTPrint_UTF16_BOM(ostream&os,BOOLisBigEndian=FALSE);
  165. };
  166. /*------------------------------
  167. END
  168. ------------------------------*/

UnicodeConverter.cpp

  1. #include"UnicodeConverter.h"
  2. /*-------------------------------------------------------------
  3. 内码转换
  4. -------------------------------------------------------------*/
  5. //转换UCS4编码到UTF8编码
  6. INTCUnicodeConverter::UCS4_To_UTF8(DWORDdwUCS4,BYTE*pbUTF8)
  7. {
  8. constBYTEabPrefix[]={0,0xC0,0xE0,0xF0,0xF8,0xFC};
  9. constDWORDadwCodeUp[]={
  10. 0x80,//U+00000000~U+0000007F
  11. 0x800,//U+00000080~U+000007FF
  12. 0x10000,//U+00000800~U+0000FFFF
  13. 0x200000,//U+00010000~U+001FFFFF
  14. 0x4000000,//U+00200000~U+03FFFFFF
  15. 0x80000000//U+04000000~U+7FFFFFFF
  16. };
  17. INTi,iLen;
  18. //根据UCS4编码范围确定对应的UTF-8编码字节数
  19. iLen=sizeof(adwCodeUp)/sizeof(DWORD);
  20. for(i=0;i<iLen;i++)
  21. {
  22. if(dwUCS4<adwCodeUp[i])
  23. {
  24. break;
  25. }
  26. }
  27. if(i==iLen)return0;//无效的UCS4编码
  28. iLen=i+1;//UTF-8编码字节数
  29. if(pbUTF8!=NULL)
  30. {//转换为UTF-8编码
  31. for(;i>0;i--)
  32. {
  33. pbUTF8[i]=static_cast<BYTE>((dwUCS4&0x3F)|0x80);
  34. dwUCS4>>=6;
  35. }
  36. pbUTF8[0]=static_cast<BYTE>(dwUCS4|abPrefix[iLen-1]);
  37. }
  38. returniLen;
  39. }
  40. //转换UTF8编码到UCS4编码
  41. INTCUnicodeConverter::UTF8_To_UCS4(constBYTE*pbUTF8,DWORD&dwUCS4)
  42. {
  43. INTi,iLen;
  44. BYTEb;
  45. if(pbUTF8==NULL)
  46. {//参数错误
  47. return0;
  48. }
  49. b=*pbUTF8++;
  50. if(b<0x80)
  51. {
  52. dwUCS4=b;
  53. return1;
  54. }
  55. if(b<0xC0||b>0xFD)
  56. {//非法UTF8
  57. return0;
  58. }
  59. if(b<0xE0)
  60. {
  61. dwUCS4=b&0x1F;
  62. iLen=2;
  63. }
  64. elseif(b<0xF0)
  65. {
  66. dwUCS4=b&0x0F;
  67. iLen=3;
  68. }
  69. elseif(b<0xF8)
  70. {
  71. dwUCS4=b&7;
  72. iLen=4;
  73. }
  74. elseif(b<0xFC)
  75. {
  76. dwUCS4=b&3;
  77. iLen=5;
  78. }
  79. else
  80. {
  81. dwUCS4=b&1;
  82. iLen=6;
  83. }
  84. for(i=1;i<iLen;i++)
  85. {
  86. b=*pbUTF8++;
  87. if(b<0x80||b>0xBF)
  88. {//非法UTF8
  89. break;
  90. }
  91. dwUCS4=(dwUCS4<<6)+(b&0x3F);
  92. }
  93. if(i<iLen)
  94. {//非法UTF8
  95. return0;
  96. }
  97. else
  98. {
  99. returniLen;
  100. }
  101. }
  102. //转换UCS4编码到UCS2编码
  103. INTCUnicodeConverter::UCS4_To_UTF16(DWORDdwUCS4,WORD*pwUTF16)
  104. {
  105. if(dwUCS4<=0xFFFF)
  106. {
  107. if(pwUTF16!=NULL)
  108. {
  109. *pwUTF16=static_cast<WORD>(dwUCS4);
  110. }
  111. return1;
  112. }
  113. elseif(dwUCS4<=0xEFFFF)
  114. {
  115. if(pwUTF16!=NULL)
  116. {
  117. pwUTF16[0]=static_cast<WORD>(0xD800+(dwUCS4>>10)-0x40);//高10位
  118. pwUTF16[1]=static_cast<WORD>(0xDC00+(dwUCS4&0x03FF));//低10位
  119. }
  120. return2;
  121. }
  122. else
  123. {
  124. return0;
  125. }
  126. }
  127. //转换UCS2编码到UCS4编码
  128. INTCUnicodeConverter::UTF16_To_UCS4(constWORD*pwUTF16,DWORD&dwUCS4)
  129. {
  130. WORDw1,w2;
  131. if(pwUTF16==NULL)
  132. {//参数错误
  133. return0;
  134. }
  135. w1=pwUTF16[0];
  136. if(w1>=0xD800&&w1<=0xDFFF)
  137. {//编码在替代区域(SurrogateArea)
  138. if(w1<0xDC00)
  139. {
  140. w2=pwUTF16[1];
  141. if(w2>=0xDC00&&w2<=0xDFFF)
  142. {
  143. dwUCS4=(w2&0x03FF)+(((w1&0x03FF)+0x40)<<10);
  144. return2;
  145. }
  146. }
  147. return0;//非法UTF16编码
  148. }
  149. else
  150. {
  151. dwUCS4=w1;
  152. return1;
  153. }
  154. }
  155. //转换UTF8字符串到UTF16字符串
  156. INTCUnicodeConverter::UTF8Str_To_UTF16Str(constBYTE*pbszUTF8Str,WORD*pwszUTF16Str)
  157. {
  158. INTiNum,iLen;
  159. DWORDdwUCS4;
  160. if(pbszUTF8Str==NULL)
  161. {//参数错误
  162. return0;
  163. }
  164. iNum=0;//统计有效字符个数
  165. while(*pbszUTF8Str)
  166. {//UTF8编码转换为UCS4编码
  167. iLen=UTF8_To_UCS4(pbszUTF8Str,dwUCS4);
  168. if(iLen==0)
  169. {//非法的UTF8编码
  170. return0;
  171. }
  172. pbszUTF8Str+=iLen;
  173. //UCS4编码转换为UTF16编码
  174. iLen=UCS4_To_UTF16(dwUCS4,pwszUTF16Str);
  175. if(iLen==0)
  176. {
  177. return0;
  178. }
  179. if(pwszUTF16Str!=NULL)
  180. {
  181. pwszUTF16Str+=iLen;
  182. }
  183. iNum+=iLen;
  184. }
  185. if(pwszUTF16Str!=NULL)
  186. {
  187. *pwszUTF16Str=0;//写入字符串结束标记
  188. }
  189. returniNum;
  190. }
  191. //转换UTF16字符串到UTF8字符串
  192. INTCUnicodeConverter::UTF16Str_To_UTF8Str(constWORD*pwszUTF16Str,BYTE*pbszUTF8Str)
  193. {
  194. INTiNum,iLen;
  195. DWORDdwUCS4;
  196. if(pwszUTF16Str==NULL)
  197. {//参数错误
  198. return0;
  199. }
  200. iNum=0;
  201. while(*pwszUTF16Str)
  202. {//UTF16编码转换为UCS4编码
  203. iLen=UTF16_To_UCS4(pwszUTF16Str,dwUCS4);
  204. if(iLen==0)
  205. {//非法的UTF16编码
  206. return0;
  207. }
  208. pwszUTF16Str+=iLen;
  209. //UCS4编码转换为UTF8编码
  210. iLen=UCS4_To_UTF8(dwUCS4,pbszUTF8Str);
  211. if(iLen==0)
  212. {
  213. return0;
  214. }
  215. if(pbszUTF8Str!=NULL)
  216. {
  217. pbszUTF8Str+=iLen;
  218. }
  219. iNum+=iLen;
  220. }
  221. if(pbszUTF8Str!=NULL)
  222. {
  223. *pbszUTF8Str=0;//写入字符串结束标记
  224. }
  225. returniNum;
  226. }
  227. /*-------------------------------------------------------------
  228. C文件写入操作
  229. -------------------------------------------------------------*/
  230. //向文件中输出UTF8编码
  231. UINTCUnicodeConverter::Print_UTF8_By_UCS4(FILE*out,DWORDdwUCS4)
  232. {
  233. INTiLen;
  234. BYTEabUTF8[8];
  235. if(out==NULL)
  236. {
  237. return0;
  238. }
  239. iLen=UCS4_To_UTF8(dwUCS4,abUTF8);
  240. if(iLen==0)return0;
  241. fwrite(abUTF8,1,iLen,out);
  242. returniLen;
  243. }
  244. //向文件中输出UTF16编码
  245. UINTCUnicodeConverter::Print_UTF16_By_UCS4(FILE*out,DWORDdwUCS4,BOOLisBigEndian)
  246. {
  247. INTi,iLen;
  248. WORDwCode,awUTF16[2];
  249. if(out==NULL)
  250. {
  251. return0;
  252. }
  253. iLen=UCS4_To_UTF16(dwUCS4,awUTF16);
  254. if(iLen==0)return0;
  255. for(i=0;i<iLen;i++)
  256. {
  257. wCode=awUTF16[i];
  258. if(isBigEndian)
  259. {
  260. fputc(wCode>>8,out);//输出高位
  261. fputc(wCode&0xFF,out);//输出低位
  262. }
  263. else
  264. {
  265. fputc(wCode&0xFF,out);//输出低位
  266. fputc(wCode>>8,out);//输出高位
  267. }
  268. }
  269. return(iLen<<1);
  270. }
  271. //将UTF16字符串以UTF8编码输出到文件中
  272. UINTCUnicodeConverter::Print_UTF8Str_By_UTF16Str(FILE*out,constWORD*pwszUTF16Str)
  273. {
  274. INTiCount,iLen;
  275. DWORDdwUCS4;
  276. if((out==NULL)||(pwszUTF16Str==NULL))
  277. {
  278. return0;
  279. }
  280. iCount=0;
  281. while(*pwszUTF16Str)
  282. {//将UTF16编码转换成UCS4编码
  283. iLen=UTF16_To_UCS4(pwszUTF16Str,dwUCS4);
  284. if(iLen==0)
  285. {
  286. break;
  287. }
  288. pwszUTF16Str+=iLen;
  289. //向文件中输出UTF8编码
  290. iCount+=Print_UTF8_By_UCS4(out,dwUCS4);
  291. }
  292. returniCount;//输出的字节数
  293. }
  294. //将UTF8字符串以UTF16编码输出到文件中
  295. UINTCUnicodeConverter::Print_UTF16Str_By_UTF8Str(FILE*out,constBYTE*pbszUTF8Str,BOOLisBigEndian)
  296. {
  297. INTiCount,iLen;
  298. DWORDdwUCS4;
  299. if((out==NULL)||(pbszUTF8Str==NULL))
  300. {
  301. return0;
  302. }
  303. iCount=0;
  304. while(*pbszUTF8Str)
  305. {//将UTF16编码转换成UCS4编码
  306. iLen=UTF8_To_UCS4(pbszUTF8Str,dwUCS4);
  307. if(iLen==0)
  308. {
  309. break;
  310. }
  311. pbszUTF8Str+=iLen;
  312. //向文件中输出UTF8编码
  313. iCount+=Print_UTF16_By_UCS4(out,dwUCS4,isBigEndian);
  314. }
  315. returniCount;//输出的字节数
  316. }
  317. //向文件中输出UTF8字节序标记
  318. UINTCUnicodeConverter::Print_UTF8_BOM(FILE*out)
  319. {
  320. if(out==NULL)
  321. {
  322. return0;
  323. }
  324. fputc(0xEF,out);
  325. fputc(0xBB,out);
  326. fputc(0xBF,out);
  327. return3;
  328. }
  329. //向文件中输出UTF16字节序标记
  330. UINTCUnicodeConverter::Print_UTF16_BOM(FILE*out,BOOLisBigEndian)
  331. {
  332. if(out==NULL)
  333. {
  334. return0;
  335. }
  336. if(isBigEndian)
  337. {
  338. fputc(0xFE,out);
  339. fputc(0xFF,out);
  340. }
  341. else
  342. {
  343. fputc(0xFF,out);
  344. fputc(0xFE,out);
  345. }
  346. return2;
  347. }
  348. /*-------------------------------------------------------------
  349. C++流输出操作
  350. -------------------------------------------------------------*/
  351. //向流中输出UTF8编码
  352. UINTCUnicodeConverter::Print_UTF8_By_UCS4(ostream&os,DWORDdwUCS4)
  353. {
  354. INTiLen;
  355. BYTEabUTF8[8];
  356. if(!os)return0;
  357. iLen=UCS4_To_UTF8(dwUCS4,abUTF8);
  358. if(iLen==0)return0;
  359. os.write(reinterpret_cast<CHAR*>(abUTF8),iLen);
  360. returniLen;
  361. }
  362. //向流中输出UTF16编码
  363. UINTCUnicodeConverter::Print_UTF16_By_UCS4(ostream&os,DWORDdwUCS4,BOOLisBigEndian)
  364. {
  365. INTi,iLen;
  366. WORDwCode,awUTF16[2];
  367. if(!os)return0;
  368. iLen=UCS4_To_UTF16(dwUCS4,awUTF16);
  369. if(iLen==0)return0;
  370. for(i=0;i<iLen;i++)
  371. {
  372. wCode=awUTF16[i];
  373. if(isBigEndian)
  374. {
  375. os.put(wCode>>8);//输出高位
  376. os.put(wCode&0xFF);//输出低位
  377. }
  378. else
  379. {
  380. os.put(wCode&0xFF);//输出低位
  381. os.put(wCode>>8);//输出高位
  382. }
  383. }
  384. return(iLen<<1);
  385. }
  386. //将UTF16字符串以UTF8编码输出到流中
  387. UINTCUnicodeConverter::Print_UTF8Str_By_UTF16Str(ostream&os,constWORD*pwszUTF16Str)
  388. {
  389. INTiCount,iLen;
  390. DWORDdwUCS4;
  391. if(!os||(pwszUTF16Str==NULL))return0;
  392. iCount=0;
  393. while(*pwszUTF16Str)
  394. {//将UTF16编码转换成UCS4编码
  395. iLen=UTF16_To_UCS4(pwszUTF16Str,dwUCS4);
  396. if(iLen==0)
  397. {
  398. break;
  399. }
  400. pwszUTF16Str+=iLen;
  401. //向流中输出UTF8编码
  402. iCount+=Print_UTF8_By_UCS4(os,dwUCS4);
  403. }
  404. returniCount;//输出的字节数
  405. }
  406. //将UTF8字符串以UTF16编码输出到流中
  407. UINTCUnicodeConverter::Print_UTF16Str_By_UTF8Str(ostream&os,constBYTE*pbszUTF8Str,BOOLisBigEndian)
  408. {
  409. INTiCount,iLen;
  410. DWORDdwUCS4;
  411. if(!os||(pbszUTF8Str==NULL))return0;
  412. iCount=0;
  413. while(*pbszUTF8Str)
  414. {//将UTF16编码转换成UCS4编码
  415. iLen=UTF8_To_UCS4(pbszUTF8Str,dwUCS4);
  416. if(iLen==0)
  417. {
  418. break;
  419. }
  420. pbszUTF8Str+=iLen;
  421. //向流中输出UTF8编码
  422. iCount+=Print_UTF16_By_UCS4(os,dwUCS4,isBigEndian);
  423. }
  424. returniCount;//输出的字节数
  425. }
  426. //向流中输出UTF8字节序标记
  427. UINTCUnicodeConverter::Print_UTF8_BOM(ostream&os)
  428. {
  429. if(!os)return0;
  430. os.put(0xEF);
  431. os.put(0xBB);
  432. os.put(0xBF);
  433. return3;
  434. }
  435. //向流中输出UTF16字节序标记
  436. UINTCUnicodeConverter::Print_UTF16_BOM(ostream&os,BOOLisBigEndian)
  437. {
  438. if(!os)return0;
  439. if(isBigEndian)
  440. {
  441. os.put(0xFE);
  442. os.put(0xFF);
  443. }
  444. else
  445. {
  446. os.put(0xFF);
  447. os.put(0xFE);
  448. }
  449. return2;
  450. }
  451. /*------------------------------
  452. END
  453. ------------------------------*/

转自:http://blog.csdn.net/jhqin/article/details/5687505

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics