字符集研究之不同字符集的转换方式
作者:朱金灿
来源:http://blog.csdn.net/clever101
在上篇文章中介绍了多字节字符集和unicode字符集,今天介绍下两大字符集之间的转换方式。
首先谈谈的是微软对于unicode字符集的态度。在windows的开发体系下。unicode字符字符集被称为宽字节字符集,多字节字符集被称为窄字符集。微软对unicode字符集是大力支持的。从下面几点能够看出:从windows2000開始使用unicode进行开发;Windows CE 本身就是使用Unicode的一种操作系统,全然不支持ANSI版Windows API函数。新建的VCproject默认使用的是unicode字符集(utf16)。那么问题来了,作为一个C++程序猿,是否该使用unicode字符集。
为什么使用Unicode字符集?
提升执行效率。比方Windows内核本身是基于unicode字符的,非unicode字符传进入要先转成unicode字符(《windows核心编程有详解》)。在不同语言中能够方便交换数据,比方在英文版操作系统中输入中文路径。假设是非unicode字符同一时候又没有安装中文字符集,那么就会出现乱码。
为什么不使用Unicode字符集?由于传统的势力非常强大,非常多跨平台的第三方库都是基于多字节字节集进行开发,还有就是编程习惯,比方在Windows下开发,大家耳熟能详的是计算字符串长度的函数是strlen。谁会去用宽字节版的wcslen呢。
详见我曾经写的文章:
最后谈谈多字节字符集和unicode字符集。
两种方式。一种是使用跨平台的iconv库,演示样例代码例如以下:
include <stdio.h> #include <stdlib.h> #include <string> using namespace std; #include <iconv.h> //编码转换库 #define OUTLEN 255 //文件路径长度 //代码转换:从一种编码转为还有一种编码 int code_convert(char *from_charset, char *to_charset, char *inbuf, size_t inlen, char *outbuf, size_t outlen) { iconv_t cd; char **pin = &inbuf; char **pout = &outbuf; cd = iconv_open(to_charset,from_charset); if (cd==0) return -1; memset(outbuf,0,outlen); if (iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1; iconv_close(cd); return 0; } //UNICODE码转为GB2312码 int u2g(char *inbuf, size_t inlen, char *outbuf, size_t outlen) { return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen); } //GB2312码转为UNICODE码 int g2u(char *inbuf, size_t inlen, char *outbuf, size_t outlen) { return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen); } //执行SQL语句回调函数 static int _sql_callback(void* pUsed, int argc, char** argv, char** ppszColName) { for(int i=0; i<argc; i++) { printf("%s = %s/n", ppszColName[i], argv[i]==0 ? "NULL" : argv[i]); } return 0; } void main() { char *in_gb2312 = "D://控制点库//GCPDB.3sdb"; char out[OUTLEN]; //gb2312码转为unicode码 g2u(in_gb2312,strlen(in_gb2312),out,OUTLEN); printf("gb2312-->unicode out=%s /n",out); }
还有一种方式是使用使用WindiwsAPI,演示样例代码例如以下:
std::string MbcsToUtf8( const char* pszMbcs ) { std::string str; WCHAR *pwchar=0; CHAR *pchar=0; int len=0; int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; len=MultiByteToWideChar(codepage, 0, pszMbcs, -1, NULL,0); pwchar=new WCHAR[len]; if(pwchar!=0) { len = MultiByteToWideChar(codepage, 0, pszMbcs, -1, pwchar, len); if( len!=0 ) { len = WideCharToMultiByte(CP_UTF8, 0, pwchar, -1, 0, 0, 0, 0); pchar=new CHAR[len]; if(pchar!=0) { len = WideCharToMultiByte(CP_UTF8, 0, pwchar, -1, pchar, len,0, 0); if(len!=0) { str = pchar; } delete pchar; } delete pwchar; } } return str; }
參考文献:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架