为了支持多语言,需要支持宽字符,Linux下用wchar_t表示,wchar_t最大长度4个字节,已经可以囊括世界上所有的语言编码,中文字符在gb2312编码下用2个字节表示,但用utf-8编码需要3个字节表示。
Linux下的系统调用,大部分都已经有对应的宽字符版本。具体可参照对照表
但仍有一些系统调用是没有宽字符版本的,例如fopen系列函数:
FILE *fopen(const char *path, const char *mode);
首先要设置本地区域
setlocale(LC_CTYPE, "zh_CN.utf8");
然后进行转换
/**
* 用malloc申请了空间,需要在外面释放
*/
int to_wchar(wchar_t **ppDest, const char *pSrc)
{
int len = 0;
int ret = 0;
len = strlen(pSrc) + 1;
if (len <= 1) return 0;
*ppDest = malloc (len);
/*这里的len应该为宽字符长度,而非源字符串的字节长度,但字节长度肯定大于宽字符长度,因此暂且用之*/
ret = mbstowcs(*ppDest, pSrc, len);
return ret;
}
/**
* 用malloc申请了空间,需要在外面释放
*/
int wtochar(char **ppDest, const wchar_t *pSrc)
{
int len = 0;
int ret = 0;
len = wcslen(pSrc) + 1;
if (len <= 1) return 0;
/*sizeof(wchar_t) = 4 */
*ppDest = malloc (len * sizeof(wchar_t));
/*这里的第三个长度参数,应为字节长度,即宽字符长度 * 4 */
ret = wcstombs(*ppDest, pSrc, len * sizeof(wchar_t));
return ret;
}
测试程序:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <wchar.h>
#include <locale.h>
#define array_size(ar) (sizeof(ar) / sizeof(ar[0]))
wchar_t *to_wchar(wchar_t **ppDest, const char *pSrc)
{
int len = 0;
int ret = 0;
len = strlen(pSrc) + 1;
if (len <= 1) return *ppDest;
*ppDest = (wchar_t*)malloc (len*sizeof(wchar_t));
/*如果第一个参数为NULL,则可以用来返回宽字符的长度*/
printf ("len:%ld\n", mbstowcs(NULL,pSrc,0)+1);
ret = mbstowcs(*ppDest, pSrc, len);
return *ppDest;
}
int main()
{
char *a = "一";
wchar_t *b = L"1s一";
wchar_t *c = L"1s一";
wchar_t *pbuf;
wchar_t wbuf[100];
setlocale(LC_CTYPE, "zh_CN.utf8");
printf ("len:%ld\n", strlen(a));
printf ("wlen:%ld\n", wcslen(b));
to_wchar(&pbuf, "1s壹");
free(pbuf);
printf ("wbuf sieof:%ld\n", sizeof(wbuf));
printf ("wbuf array sizeof:%ld\n", array_size(wbuf));
return 0;
}
输出结果:
[root@23 test]# ./test_hanzi
len:3
wlen:3
len:4
wbuf sieof:400 // sizeof (宽字符) = 所占字节的总长度 = 宽字符长度 * 4
wbuf array sizeof:100