字符集研究之不同字符集的转换方式

旧城等待, 2022-08-21 02:29 245阅读 0赞

作者:朱金灿

来源:http://blog.csdn.net/clever101

  1. 在上篇文章中介绍了多字节字符集和unicode字符集,今天介绍下两大字符集之间的转换方式。
  2. 首先谈谈的是微软对于unicode字符集的态度。在windows的开发体系下,unicode字符字符集被称为宽字节字符集,多字节字符集被称为窄字符集。微软对unicode字符集是大力支持的。从以下几点可以看出:从windows2000开始使用unicode进行开发;Windows CE 本身就是使用Unicode的一种操作系统,完全不支持ANSIWindows API函数;新建的VC工程默认使用的是unicode字符集(utf16)。那么问题来了,作为一个C++程序员,是否该使用unicode字符集。
  3. 为什么使用Unicode字符集?提升运行效率,比如Windows内核本身是基于unicode字符的,非unicode字符传进入要先转成unicode字符(《windows核心编程有详细解释》);在不同语言中可以方便交换数据,比如在英文版操作系统中输入中文路径,如果是非unicode字符同时又没有安装中文字符集,那么就会出现乱码。
  4. 为什么不使用Unicode字符集?因为传统的势力很强大,很多跨平台的第三方库都是基于多字节字节集进行开发,还有就是编程习惯,比如在Windows下开发,大家耳熟能详的是计算字符串长度的函数是strlen,谁会去用宽字节版的wcslen呢。详见我以前写的文章:

《unicode字符集,用还是不用?》

  1. 最后谈谈多字节字符集和unicode字符集。两种方式,一种是使用跨平台的iconv库,示例代码如下:
  2. include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string>
  5. using namespace std;
  6. #include <iconv.h> //编码转换库
  7. #define OUTLEN 255 //文件路径长度
  8. //代码转换:从一种编码转为另一种编码
  9. int code_convert(char *from_charset, char *to_charset, char *inbuf, size_t inlen, char *outbuf, size_t outlen)
  10. {
  11. iconv_t cd;
  12. char **pin = &inbuf;
  13. char **pout = &outbuf;
  14. cd = iconv_open(to_charset,from_charset);
  15. if (cd==0)
  16. return -1;
  17. memset(outbuf,0,outlen);
  18. if (iconv(cd,pin,&inlen,pout,&outlen)==-1)
  19. return -1;
  20. iconv_close(cd);
  21. return 0;
  22. }
  23. //UNICODE码转为GB2312码
  24. int u2g(char *inbuf, size_t inlen, char *outbuf, size_t outlen)
  25. {
  26. return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
  27. }
  28. //GB2312码转为UNICODE码
  29. int g2u(char *inbuf, size_t inlen, char *outbuf, size_t outlen)
  30. {
  31. return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen);
  32. }
  33. //执行SQL语句回调函数
  34. static int _sql_callback(void* pUsed, int argc, char** argv, char** ppszColName)
  35. {
  36. for(int i=0; i<argc; i++)
  37. {
  38. printf("%s = %s/n", ppszColName[i], argv[i]==0 ? "NULL" : argv[i]);
  39. }
  40. return 0;
  41. }
  42. void main()
  43. {
  44. char *in_gb2312 = "D://控制点库//GCPDB.3sdb";
  45. char out[OUTLEN];
  46. //gb2312码转为unicode码
  47. g2u(in_gb2312,strlen(in_gb2312),out,OUTLEN);
  48. printf("gb2312-->unicode out=%s /n",out);
  49. }

另一种方式是使用使用WindiwsAPI,示例代码如下:

  1. std::string MbcsToUtf8( const char* pszMbcs )
  2. {
  3. std::string str;
  4. WCHAR *pwchar=0;
  5. CHAR *pchar=0;
  6. int len=0;
  7. int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
  8. len=MultiByteToWideChar(codepage, 0, pszMbcs, -1, NULL,0);
  9. pwchar=new WCHAR[len];
  10. if(pwchar!=0)
  11. {
  12. len = MultiByteToWideChar(codepage, 0, pszMbcs, -1, pwchar, len);
  13. if( len!=0 )
  14. {
  15. len = WideCharToMultiByte(CP_UTF8, 0, pwchar, -1, 0, 0, 0, 0);
  16. pchar=new CHAR[len];
  17. if(pchar!=0)
  18. {
  19. len = WideCharToMultiByte(CP_UTF8, 0, pwchar, -1, pchar, len,0, 0);
  20. if(len!=0)
  21. {
  22. str = pchar;
  23. }
  24. delete pchar;
  25. }
  26. delete pwchar;
  27. }
  28. }
  29. return str;
  30. }

参考文献:

  1. 使用SQLite3支持中文路径

发表评论

表情:
评论列表 (有 0 条评论,245人围观)

还没有评论,来说两句吧...

相关阅读