cs(wchar_t *wcstr,const char *mbstr,size_t count);
这个函数的第三个参数count,大小一定要是mbstr长度的2倍,否则出来的中文也会是乱码。
iconv库函数的使用
#include
iconv_t iconv_open(const char *tocode, const char *fromcode);
size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);
int iconv_close(iconv_t cd);
iconv函数的使用需要setlocale() 这个函数设置环境:如:setlocale(LC_ALL,"zh_CN.GB18030");
linux下的库函数使用麻烦而且易出错,可以使用下列函数
// 检查字符串中是不是有需要转换的宽字符(utf-8编码中的宽字符),当然该函数不能识别是不是unicode编码,只能识别中文等等多字节字符的特征
bool CheckIsUTF8(const char *put_in, int size)
{
if (put_in != NULL && size-- > 0) // size减1预先去掉结尾位置,所有size因为是实际长度+1
{
while (*put_in != 0 && size > 0) // 遍历
{
unsigned char ch = *put_in;
if (ch > 0x7FU) // 检查是不是utf8编码,是的话一次取完,(UTF-8没有大小端的问题)
{
int cwch = 0; // 记录个数
while (ch & 0x80U)
{
ch <<= 1;
cwch++;
}
if (cwch > 6 || cwch < 1) // 超过了最大识别边界
{
put_in++;
size--;
continue;
}
unsigned char ch_g = *put_in++;
size--;
bool isTrue = true;
while (--cwch > 0 && *put_in != 0 && size > 0) // 递减验证
{
if (0x80U != ch_g & 0x80U) // 表示没有
{
isTrue = false;
}
ch_g = *put_in++;
size--;
}
if (isTrue)
{
return true; // 表示包含宽字符编码
}
}
else
{
put_in++;
size--;
}
}
}
int UTF8ToUTF16(const char *pmbs, wchar_t *pwcs, int size) // pmbs需要有边界以0结尾,size表示字符个数
{
int cnt = 0;
if (pmbs != NULL && pwcs != NULL && size-- > 0) // size减1预先去掉结尾位置,所有size因为是实际长度+1
{
while (*pmbs != 0 && size > 0) // 遍历
{
unsigned char ch = *pmbs;
//printf("%c %x\n", ch,ch);
if (ch > 0x7FU) // 检查是不是utf8编码,是的话一次取完,(UTF-8没有大小端的问题)
{
int cwch = 0; // 记录个数
while (ch & 0x80U) // 检查字符头是不是宽字符标记
{
ch <<= 1; // 左移一位,检查有几个字符
cwch++;
}
if (cwch > size) // 检查是不是最后几个字符
{
*pwcs = *pmbs++;
//printf("1\n");
//printf("1: %ls \n", pwcs);
}
else
{
*pwcs = *pmbs++ & (0xFFU >> cwch); // 付给第一个字符的数据值
size--;
while (--cwch > 0) // 递减,(没有做严格验证)
{
if (size <= 0)
{
*pwcs = *pmbs; // 重复复制,保证单值正确
}
else
{
*pwcs <<= 6; // 向大端平移6位(因为跟随字符都是6位有效)
*pwcs |= (*pmbs++ & 0x3FU); // 添加地位字符
size--;
}
}
//printf("2 \n");
//printf("2:%ls \n", pwcs);
}
}
else
{
*pwcs = *pmbs++; // 表示是单字节编码,直接赋值给一个宽字符(自动适应大小端)
size--;
}
//printf("3 \n");
pwcs++;
cnt++;
}
*pwcs = 0; // 以0x00
cnt++;
}
return cnt;
}
int UnicodeToUTF8(const wchar_t *pwcs, char *pmbs, int size)
{
int cnt = 0;
// 这里 size-- 是预先除去尾零所需位置
if (pwcs != NULL && pmbs != NULL && size-- > 0) {
while (*pwcs != 0 && size > 0) {
if (*pwcs < 0x00000080U) {
*pmbs++ = (char)*pwcs;
size -= 1;
cnt += 1;
}
else if (*pwcs < 0x00000800U) {
// 剩余空间不够存放该字符
if (size < 2) {
break;
}
*pmbs++ = (0xFFU << 6) | (*pwcs >> 6);
*pmbs++ = 0x80U | (*pwcs & 0x3FU);
size -= 2;
cnt += 2;
}
else if (*pwcs < 0x00010000U) {
// 剩余空间不够存放该字符
if (size < 3) {
break;
}
*pmbs++ = (0xFFU << 5) | (*pwcs >> 12);
*pmbs++ = 0x80U | ((*pwcs >> 6) & 0x3FU);
*pmbs++ = 0x80U | (*pwcs & 0x3FU);
size -= 3;
cnt += 3;
}
else if (*pwcs < 0x00200000U) {
// 剩余空间不够存放该字符
if (size < 4) {
break;
}
*pmbs++ = (0xFFU << 4) | (*pwcs >> 18);
*pmbs++ = 0x80U | ((*pwcs >> 12) & 0x3FU);
*pmbs++ = 0x80U | ((*pwcs >> 6) & 0x3FU);
*pmbs++ = 0x80U | (*pwcs & 0x3FU);
size -= 4;
cnt += 4;
}
else if (*pwcs < 0x04000000U) {
// 剩余空间不够存放该字符
if (size < 5) {
break;
}
*pmbs++ = (0xFFU << 3) | (*pwcs >> 24);
*pmbs++ = 0x80U | ((*pwcs >> 18) & 0x3FU);
*pmbs++ = 0x80U | ((*pwcs >> 12) & 0x3FU);
*pmbs++ = 0x80U | ((*pwcs >> 6) & 0x3FU);
*pmbs++ = 0x80U | (*pwcs & 0x3FU);
size -= 5;
cnt += 5;
}
else if (*pwcs < 0x80000000U) {
// 剩余空间不够存放该字符
if (size < 6) {
break;
}
*pmbs++ = (0xFFU << 2) | (*pwcs >> 30);
*pmbs++ = 0x80U | ((*pwcs >> 24) & 0x3FU);
*pmbs++ = 0x80U | ((*pwcs >> 18) & 0x3FU);
*pmbs++ = 0x80U | ((*pwcs >> 12) & 0x3FU);
*pmbs++ = 0x80U | ((*pwcs >> 6) & 0x3FU);
*pmbs++ = 0x80U | (*pwcs & 0x3FU);
size -= 6;
cnt += 6;
}
else {
// 无法识别的 Unicode 字符
break;
}
pwcs++;
}
*pmbs = 0;
cnt++;
}
return cnt;
}