标准C中多字节和宽字节的互相转换
标准C中将多字节转换为宽字节的函数是mbstowcs。将宽字节转换为多字节的函数是wcstombs。这两个函数均依赖于LC_CTYPE。具体的,你的操作系统所支持的locale,你可以通过locale –a命令查看。假如待转换的字符串中包含中文,那么locale –a应该能够看到类似zh_CN.utf8之类的。如果没有,那么以上两个函数将不能正确的对中文字符进行转换。我假设你使用Debian系统,那么你可以执行dpkg-reconfigure locales,并添加中文支持(通过位于列表的最后)。你也可能通过编辑文件/etc/locales.gen,然后运行命令locale-gen来重新配置locale信息。这两个函数的原型分别是:
size_t wcstombs(char *dest, const wchar_t *src, size_t n);
size_t mbstowcs(wchar_t *dest, const char *src, size_t n);
其中,dest保存转换后的字符串,src为待转换字符串,n为dest的空间大小。其返回值为已经转换的源字符串个数。如果返回-1,则表示转换失败。
下面让我们来假设这样一种应用场景:有一个用C语言编写的客户端程序需要和mysql数据库通信,它有可能会插入商品数据到数据库中,也有可能会从数据库中读取商品数据。现在的问题是这些商品数据中包含中文,而且,mysql数据库采用utf8来保存这些数据。很显然,你需要在utf8和ascii之间转换。对于mysql数据库你可以通过执行sql语句set names utf8来告诉mysql用utf8编码来保存数据。同样的,该条语句也告诉mysql以utf8取出数据。以C语言为例,将char转换到wchar_t的代码为:
setlocale(LC_CTYPE,“zh_CN.utf8”);//可以通过locale –a | grep zh_CN*查看
char* pSrc = “测试”;
wchar_t* pDest = NULL;
int nLen,nSize;
nSize = mbstowcs(NULL, pSrc, NULL);//求目标空间长度
pDest = (wchar_t*)malloc(nSize + 1);//分配空间
nLen = mbstowcs(pDest, pSrc, nSize + 1);//执行转换
printf(“%ls\n”, pDest);// 显示到终端
free(pDest);// 释放空间
顺便再说一句,通过mysql_fetch_row函数返回的MYSQL_ROW结构,如果结构中包含字符串,那么字符串是char*的,也就是说,mysql没有wchar_t版本的(对于这一点我没有作更多的考证)。既然这样,那么mysql_fetch_row自己内部会为我们作字符串编码的转换工作,但他是怎样知道源字符串的编码呢?答案就是set names utf8这一句告诉mysql源字符串的编码是utf8形式的。足见它的重要性了吧?
另外一个函数的用法同上。对于文件的转换,可以采用iconv系统调用。在windows平台下,可以调用WideCharToMultiByte和MultiByteToWideChar。