65.9K
CodeProject 正在变化。 阅读更多。
Home

UTF16 到 UTF8 到 UTF16 的简单 CString 转换

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.20/5 (15投票s)

2008年5月16日

CPOL
viewsIcon

153970

使用 CString 在 UTF8 和 UTF16 之间进行转换。

引言

对于 UTF8 和 UTF16(以及其他格式)之间的字符串转换,微软提供了 MultiByteToWideCharWideCharToMultiByte 函数。这些函数使用以空字符结尾的 char/widechar 字符串。使用这些字符串需要进行一些内存管理,如果您大量使用这些函数,您的代码可能会变得一团糟。因此,我决定为与更易于编码的 CString 类型一起使用而封装这两个函数。

转换函数

UTF16toUTF8

CStringA UTF16toUTF8(const CStringW& utf16)
{
   CStringA utf8;
   int len = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, 0, 0);
   if (len>1)
   { 
      char *ptr = utf8.GetBuffer(len-1);
      if (ptr) WideCharToMultiByte(CP_UTF8, 0, utf16, -1, ptr, len, 0, 0);
      utf8.ReleaseBuffer();
   }
   return utf8;
}

UTF8toUTF16

CStringW UTF8toUTF16(const CStringA& utf8)
{
   CStringW utf16;
   int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
   if (len>1)
   { 
      wchar_t *ptr = utf16.GetBuffer(len-1);
      if (ptr) MultiByteToWideChar(CP_UTF8, 0, utf8, -1, ptr, len);
      utf16.ReleaseBuffer();
   }
   return utf16;
}

使用代码

这两个辅助函数的用法很简单。但是,请注意,只有当您的项目设置为使用 UNICODE 字符集时,它们才有效。这些函数也仅适用于 Visual Studio 7.1 或更高版本。如果您使用 Visual Studio 6.0,您将无法编译,因为缺少 CStringACStringW。在下面的代码片段中,您有一个用法示例

CStringW utf16("òèçùà12345");
CStringA utf8 = UTF16toUTF8(utf16);
CStringW utf16_2 = UTF8toUTF16(utf8);

历史

Ivo Beltchev 的评论之后,我决定按照他的建议更改这些函数。最初,我将函数设计成这样

CStringA UTF16toUTF8(const CStringW& utf16)
{
  LPSTR pszUtf8 = NULL;
  CStringA utf8("");

  if (utf16.IsEmpty()) 
    return utf8; //empty imput string

  size_t nLen16 = utf16.GetLength();
  size_t nLen8 = 0;

  if ((nLen8 = WideCharToMultiByte (CP_UTF8, 0, utf16, nLen16, 
                                    NULL, 0, 0, 0) + 2) == 2)
    return utf8; //conversion error!

  pszUtf8 = new char [nLen8];
  if (pszUtf8)
  {
    memset (pszUtf8, 0x00, nLen8);
    WideCharToMultiByte(CP_UTF8, 0, utf16, nLen16, pszUtf8, nLen8, 0, 0);
    utf8 = CStringA(pszUtf8);
  }

  delete [] pszUtf8;
  return utf8; //utf8 encoded string
}

CStringW UTF8toUTF16(const CStringA& utf8)
{
  LPWSTR pszUtf16 = NULL;
  CStringW utf16("");
  
  if (utf8.IsEmpty()) 
    return utf16; //empty imput string

  size_t nLen8 = utf8.GetLength();
  size_t nLen16 = 0;

  if ((nLen16 = MultiByteToWideChar (CP_UTF8, 0, utf8, nLen8, NULL, 0)) == 0)
    return utf16; //conversion error!

  pszUtf16 = new wchar_t[nLen16];
  if (pszUtf16)
  {
    wmemset (pszUtf16, 0x00, nLen16);
    MultiByteToWideChar (CP_UTF8, 0, utf8, nLen8, pszUtf16, nLen16);
    utf16 = CStringW(pszUtf16);
  }

  delete [] utf16;
  return utf16; //utf16 encoded string
}

这些函数同样有效,但后来的版本更小且经过了一些优化。感谢 Ivo 的观察!

© . All rights reserved.