如何将Unicode字符串转换为utf-8或utf-16字符串?

时间:2008-11-11 08:38:53

标签: c++ unicode utf-8 character-encoding utf-16

如何将Unicode字符串转换为utf-8或utf-16字符串? 我的VS2005项目使用Unicode字符集,而cppite中的sqlite提供

int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
int sqlite3_open16(
  const void *filename,   /* Database filename (UTF-16) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);

用于打开文件夹。 如何将字符串,CString或wstring转换为UTF-8或UTF-16字符集?

非常感谢!

5 个答案:

答案 0 :(得分:8)

使用WideCharToMultiByte功能。为CP_UTF8参数指定CodePage

CHAR buf[256]; // or whatever
WideCharToMultiByte(
  CP_UTF8, 
  0, 
  StringToConvert, // the string you have
  -1, // length of the string - set -1 to indicate it is null terminated
  buf, // output
  __countof(buf), // size of the buffer in bytes - if you leave it zero the return value is the length required for the output buffer
  NULL,    
  NULL
);

此外,Windows中unicode应用程序的默认编码为UTF-16LE,因此您可能不需要执行任何翻译,只需使用第二个版本sqlite3_open16

答案 1 :(得分:7)

简短回答:

如果使用CString或wstring等Unicode字符串,则无需转换。使用sqlite3_open16()。 你必须确保你传递一个WCHAR指针(转换为void *。看起来很蹩脚!即使这个lib是跨平台的,我猜他们可能已经定义了一个取决于平台的宽字符类型并且不那么不友好而不是void *)API。例如对于CString:(void*)(LPCWSTR)strFilename

答案越久:

您没有要转换为UTF8或UTF16的Unicode字符串。您在程序中使用给定的编码表示Unicode字符串:Unicode本身不是二进制表示形式。编码说明Unicode代码点(数值)如何在内存中表示(数字的二进制布局)。 UTF8和UTF16是使用最广泛的编码。但它们非常不同。

当一个VS项目说“Unicode charset”时,它实际上意味着“字符被编码为UTF16”。因此,您可以直接使用sqlite3_open16()。无需转换。字符存储在WCHAR类型中(与char相对),它占用16位(标准C类型wchar_t上的回退,在Win32上占16位。在其他平台上可能会有所不同。感谢您的更正,Checkers)。

还有一个您可能需要注意的细节:UTF16有两种版本:Big Endian和Little Endian。这是这16位的字节顺序。您为UTF16提供的函数原型并未说明使用了哪种排序。但是你很安全,假设sqlite使用与Windows相同的字节序(Little Endian IIRC。我知道顺序,但一直有名字的问题:-))。

编辑:回答Checkers的评论:

UTF16使用16位代码单元。在Win32(以及Win32上仅 )下,wchar_t用于此类存储单元。诀窍是一些Unicode字符需要2个这样的16位代码单元的序列。他们被称为代理对。

UTF8使用1到4个字节序列表示1个字符的方式相同。然而,UTF8与char类型一起使用。

答案 2 :(得分:3)

所有C ++字符串类型都是charset中立的。他们只是在字符宽度上,并没有进一步的假设。 wstring在Windows中使用16位字符,大致对应于utf-16,但它仍然取决于您在线程中存储的内容。 wstring不以任何方式强制您放入其中的数据必须是有效的utf16。虽然定义了UNICODE,Windows使用utf16,因此很可能你的字符串已经是utf16,而且你不需要做任何事情。

其他一些人建议使用WideCharToMultiByte函数,这是将utf16转换为utf8的方法之一。但是因为sqlite可以处理utf16,所以这不是必需的。

答案 3 :(得分:0)

utf-8和utf-16都是“unicode”字符编码。您可能谈论的是utf-32,它是一个固定大小的字符编码。也许正在寻找

"Convert utf-32 into utf-8 or utf-16"

为您提供一些结果或其他论文。

答案 4 :(得分:0)

最简单的方法是使用CStringA。 CString类是CStringA(ASCII版本)或CStringW(宽字符版本)的typedef。这两个类都有构造函数来转换字符串类型。我通常使用:

sqlite3_open(CStringA(L"MyWideCharFileName"), ...);