farwang 2010-09-08
在Windows系统,可以利用WideCharToMultiByte和MultiByteToWideChar进行各种编码之间的转换
比如WideCharToMultiByte(CP_ACP,0,pszWText,wcslen(pszWText),pszAText,nATextLen,NULL,NULL);将Unicode的pszWText转换为GB2312的pszAText,其中CP_ACP为编码的代码页,不同的代码页指定了不同的编码转换,那么在Linux如何实现编码转换呢?
幸好Linux下提供了iconv实现这一功能,在Linux 的 shell 环境下,iconv用法如下:
iconv -f fromconde -t tocode
-f: 指定需要转换的文本编码
-t: 指定目标文本编码
我们也可以用 -l 列举出所有已知的字符编码集合
iconv -l
具体用法可以通过帮助函数 iconv --help来详细了解
另外,我们也可以在程序中直接使用该函数实现文本的编码转换
#ifndef __CODE_CONVERTER#define __CODE_CONVERTER
#ifdef WIN32
#include<windows.h>
#else
#include<iconv.h>
#endifclass CodeConverter
{
private:
#ifndefWIN32
iconv_tm_cd;
#endif
constchar*m_pszFromCode;
const char* m_pszToCode;public:
CodeConverter()
{
m_pszFromCode=NULL;
m_pszToCode=NULL;
#ifndefWIN32
m_cd=0;
#endif
}~CodeConverter()
{
#ifndefWIN32
iconv_close(m_cd);
#endif
}bool Initialize(const char *pszToCode, const char *pszFromCode);
size_tConvert(char*inBuf,size_tinBytesLeft,char*outBuf,size_toutBytesLen);
};#endif
#include <string.h>
#include<stdlib.h>
#include<stdio.h>
#include"code_converter.h"
#include <errno.h>bool CodeConverter::Initialize(const char* pszToCode, const char* pszFromCode)
{
if(pszFromCode == NULL || pszToCode == NULL) return false;m_pszFromCode = pszFromCode; m_pszToCode = pszToCode;
#ifndef WIN32
m_cd=iconv_open(m_pszToCode,m_pszFromCode);
if(m_cd==(iconv_t)-1)
{
printf("cannotopeniconvdescripter\n");
returnfalse;
}
#endif
returntrue;
}size_t CodeConverter:: Convert(char* inBuf, size_t inBytesLeft, char* outBuf, size_t outBytesLen)
{
intnRealLen=0;
#ifdefWIN32
if(stricmp(m_pszFromCode,"UNICODE")==0)
{
nRealLen=WideCharToMultiByte(CP_ACP,0,(PWCHAR)inBuf,inBytesLeft,(PCHAR)outBuf,outBytesLen,NULL,NULL);
}
if(stricmp(m_pszFromCode,"gb2312")==0)
{
nRealLen=MultiByteToWideChar(CP_ACP,0,(PCHAR)inBuf,inBytesLeft,(PWCHAR)outBuf,outBytesLen);
}
#elsesize_t outBytesLeft = outBytesLen;
size_tret=0;
while(1)
{
ret=iconv(m_cd,&inBuf,&inBytesLeft,&outBuf,&outBytesLeft);
if(ret==0)break;
if(ret==(size_t)-1)
{
printf("iconverroraaa:%s\n",strerror(errno));
return-1;
}
inBuf++;inBytesLeft--;
}
nRealLen=outBytesLen-outBytesLeft;
outBuf[nRealLen]=0;
#endif
returnnRealLen;
}