如何将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字符集?

非常感谢!

有帮助吗?

解决方案

简短回答:

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

其他提示

使用 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 ++字符串类型都是charset中立的。他们只是在字符宽度上,并没有进一步的假设。 wstring在Windows中使用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"

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

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

sqlite3_open(CStringA(L"MyWideCharFileName"), ...);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top