如何在Linux系统实现字符编码转换

在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>
#endif

class CodeConverter
{
private:
#ifndef WIN32
 iconv_t m_cd;
#endif
 const char* m_pszFromCode;
 const char* m_pszToCode;

public:
 CodeConverter()
    {
        m_pszFromCode = NULL;
        m_pszToCode = NULL;
#ifndef WIN32
     m_cd = 0;
#endif
    }

 ~CodeConverter()
 {
#ifndef WIN32
  iconv_close(m_cd);
#endif
 }

 bool Initialize(const char *pszToCode, const char *pszFromCode);
 size_t Convert(char* inBuf, size_t inBytesLeft, char* outBuf, size_t outBytesLen);
};

#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("cannot open iconv descripter\n");
  return false;
 }
#endif
 return true;
}

size_t CodeConverter:: Convert(char* inBuf, size_t inBytesLeft, char* outBuf, size_t outBytesLen)
{
    int nRealLen = 0;
#ifdef WIN32
 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);
 } 
#else

 size_t outBytesLeft = outBytesLen;
 size_t ret = 0;
 while (1)
 {
  ret = iconv(m_cd, &inBuf, &inBytesLeft, &outBuf, &outBytesLeft);
  if (ret == 0) break;
  if (ret == (size_t)-1)
  {
   printf("iconv error aaa: %s\n",strerror(errno));
   return -1;
  }
  inBuf++; inBytesLeft--;
 }
 nRealLen = outBytesLen-outBytesLeft;
 outBuf[nRealLen]=0;
#endif
    return nRealLen;
}

猜你喜欢

转载自langiner.iteye.com/blog/758613