设为首页 加入收藏

TOP

c++转码基础(1):各种编码类型及unicode和uft-8互转(三)
2016-09-12 19:03:12 】 浏览:774
Tags:基础 各种 编码 类型 unicode uft-8 互转
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;

}

首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++学习笔记--函数 下一篇C++ primer读书笔记第13章:拷贝..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目