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

2025-03-22 17:55:53
推荐回答(1个)
回答(1):

  在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
  #else
  #include
  #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
  #include
  #include
  #include "code_converter.h"
  #include
  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;
  }