English 中文(简体)
如何将Unicode字符串转换为utf-8或utf-16字符串?
原标题:
  • 时间:2008-11-11 08:38:52
  •  标签:

How to convert Unicode string into a utf-8 or utf-16 string? My VS2005 project is using Unicode char set, while sqlite in cpp provide

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 */
);

for opening a folder. How can I convert string, CString, or wstring into UTF-8 or UTF-16 charset?

非常感谢!

最佳回答

简短回答:

No conversion required if you use Unicode strings such as CString or wstring. Use sqlite3_open16(). You will have to make sure you pass a WCHAR pointer (casted to void *. Seems lame! Even if this lib is cross platform, I guess they could have defined a wide char type that depends on the platform and is less unfriendly than a void *) to the API. Such as for a CString: (void*)(LPCWSTR)strFilename

更长的答案:

你没有一个想要转换为UTF8或UTF16的Unicode字符串。你的程序中有一个使用给定编码表示的Unicode字符串:Unicode本身并不是二进制表示。编码表述Unicode代码点(数值)在内存中的表示方式(数字的二进制布局)。UTF8和UTF16是最常用的编码方式,但它们也有很大的不同。

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

还有一个细节需要注意:UTF16存在两种格式:Big Endian和Little Endian。这是16位字节的排序方式。你给出的UTF16函数原型没有说明使用哪种排序方式。但是你可以放心地认为sqlite使用与Windows相同的Endian-ness(我记得是Little Endian,我知道顺序但一直有问题命名:-))。

编辑:给Checkers评论的回复:

UTF16使用16位代码单元。在Win32下(并且仅仅在Win32下),wchar_t被用来作为这种存储单元。技巧是有些Unicode字符需要由两个这样的16位代码单元序列组成,它们被称为代理对。

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

问题回答

使用 WideCharToMultiByte 函数。将 CodePage 参数指定为 CP_UTF8

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即可。

所有的C++字符串类型都是字符集中性的。它们只是设定一个字符宽度,不做其他假设。在Windows中,wstring使用16位字符,大致对应于utf-16,但它仍取决于您在线程中存储的内容。wstring并不以任何方式强制要求您放入其中的数据必须是有效的utf16。当定义UNICODE时,Windows使用utf16,因此您的字符串很可能已经是utf16,您不需要做任何操作。

有些人建议使用WideCharToMultiByte函数,这是将utf16转换为utf8的(一种)方法。但是由于sqlite可以处理utf16,所以不必这样做。

utf-8和utf-16都是“Unicode”字符编码。你可能要谈论的是utf-32,它是一种固定大小的字符编码。也许搜索utf-32可以帮助你更好地了解。 UTF-8和UTF-16都是“Unicode”字符编码。你可能要讨论的是UTF-32,它是一种固定大小的字符编码。也许搜索UTF-32可以帮助您更好地了解。

"将 UTF-32 转换为 UTF-8 或 UTF-16"

提供一些有关此事的结果或其他文件。

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

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




相关问题
热门标签