不依赖任何系统API,用c语言实现gbk/utf8/unicode编码转换
转载地址:https://blog.csdn.net/bladeandmaster88/article/details/54837338
汉字'我'
Unicode编码是0x6211 01100010 00010001
UTF8编码是 0xe68891 11100110 10001000 100010001
n |
Unicode符号范围 (十六进制) |
UTF-8编码方式 (二进制) |
1 2 3 |
0x00 - 0x7F 0x80 - 0x7FF 0x800 - 0xFFFF |
0zzzzzzz 110yyyyy 10zzzzzz 1110xxxx 10yyyyyy 10zzzzzz |
4 5 6 |
0x10000 - 0x1FFFFF 0x200000 - 0x3FFFFFF 0x4000000 - 0x7FFFFFFF |
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
一、Unicode转utf8
‘我’的unicode编码0x6211,二进制为: 01000010 00010001
将二进制形式分割成3段为0110 001000010001(分别是高4位、中间的6位、最后的低6位)
unicode转utf8只需要这3段分别填入1110xxxx 10yyyyyy 10zzzzzz中的xxxx yyyyyy zzzzzz
得utf8编码是0xe6889,二进制为: 11100110 10001000 100010001
int UnicodeToUtf8(char *pInput, char *pOutput)
{int len = 0; //记录转换后的utf8字符串的字节数while (*pInput) {//处理一个unicode字符char low = *pInput; //取出unicode字符的低8位pInput++;char high = *pInput; //取出unicode字符的高8位int w=high<<8;unsigned wchar = (high<<8)+low; //高8位和低8位组成一个unicode字符,加法运算级别高if (wchar <= 0x7F) //英文字符{pOutput[len] = (char)wchar; //取wchar的低8位len++;} else if (wchar >= 0x80 && wchar <= 0x7FF) //可以转换成双字节pOutput字符{pOutput[len] = 0xc0 | ((wchar >> 6)&0x1f); //取出unicode编码低6位后的5位,填充到110yyyyy 10zzzzzz 的yyyyy中len++; pOutput[len] = 0x80 | (wchar & 0x3f); //取出unicode编码的低6位,填充到110yyyyy 10zzzzzz 的zzzzzz中len++;} else if (wchar >= 0x800 && wchar < 0xFFFF) //可以转换成3个字节的pOutput字符{pOutput[len] = 0xe0 | ((wchar >> 12)&0x0f)J; //高四位填入1110xxxx 10yyyyyy 10zzzzzz中的xxxxlen++;pOutput[len] = 0x80 | ((wchar >> 6) & 0x3f); //中间6位填入1110xxxx 10yyyyyy 10zzzzzz中的yyyyyylen++;pOutput[len] = 0x80 | (wchar & 0x3f); //低6位填入1110xxxx 10yyyyyy 10zzzzzz中的zzzzzzlen++;}else //对于其他字节数的unicode字符不进行处理{return -1;}pInput++;//处理下一个unicode字符}//utf8字符串后面,有个\0pOutput[len] = 0;return len;
}
二、utf8转unicode
utf8二进制形式为1110xxxx 10yyyyyy 10zzzzzz
'我'的utf8编码0xe6889,二进制为:11100110 10001000 100010001
分别提取里面的xxxx yyyyyy zzzzzz,然后组合成xxxxyyyy yyzzzzzz,
xxxxyyyy就是unicode的高8位,yyzzzzzz就是unicode的低8位
/*
* 将utf8编码转换成Unicode (UCS-2LE) 编码 低地址存低位字节
* 参数:
* char *pInput 输入字符串
* char *pOutput 输出字符串
* 返回值: 转换后的Unicode字符串的字节数,如果出错则返回-1
*/
//utf8转unicode
int Utf8ToUnicode(char *pInput, char *pOutput)
{int outputSize = 0; //记录转换后的Unicode字符串的字节数while(*pInput) {if (*pInput > 0x00 && *pInput <= 0x7F) //处理单字节UTF8字符(英文字母、数字){*pOutput = *pInput;pOutput++;*pOutput = 0; //小端法表示,在高地址填补0} else if (((*pInput) & 0xE0) == 0xC0) //处理双字节UTF8字节{char high = *pInput;pInput++;char middle = *pInput;pInput++;char low = *pInput;if (((middle & 0xC0) != 0x80) || ((low & 0xC0) != 0x80)) {return -1;}*pOutput = (middle << 6) + (low & 0x3F); //取出middle的低两位与low的低6位,组合成unicode字符的低8位pOutput++;*pOutput = (high << 4) + (middle >> 2) & 0x0F); //取出high的低四位与middle的中间四位,组合成unicode字符的高8位} else //对于其他字节数的UTF8字符不进行处理{return -1;}pInput ++; //处理下一个utf8字符pOutput++;outputSize += 2;
}//unicode字符串后面,有两个\0
*pOutput = 0;
pOutput++;
*pOutput = 0;
return outputSize;
//一个调用示例
int main(int argc, char **argv)
{//汉字'我'的UTF8编码是0xe68891,Unicode的编码是0x6211//1.unicode转utf8char unicodeStr[3] = {0x11, 0x62, 0x00}; //'我'的unicode是0x6211,按低地址存低位字节char *utf8Str = new char[5];memset(utf8Str, 0, 5);int num = UnicodeToUtf8(unicodeStr, utf8Str);unsigned char *p = (unsigned char *)utf8Str;for (int i=0; i<num; i++) {printf("%0x", *p);p++;}//输出e68891printf("\n");delete utf8Str;//2.utf8转unicode//char utf8Str[4] = {0xe6, 0x88, 0x91, 0x00};//char *unicodeStr = new char[8];//memset(unicodeStr, 0, 8);//int num = Utf8ToUnicode(utf8Str, unicodeStr);//if(num == -1) {// printf("Error!\n");//}//else//{// unsigned char *p = (unsigned char *)unicodeStr;// for (int i=0; i<num; i++) {// printf("%0x", *p);// p++;// }//输出1162// printf("\n");//}//delete unicodeStr;return 0;
}
三、gbk与unicode互转
代码下载地址:c语言利用编码转换表实现gbk与unicode互转
参照博客:
http://blog.csdn.net/tge7618291/article/details/7599902
http://www.ithao123.cn/content-1832906.html
不依赖任何系统API,用c语言实现gbk/utf8/unicode编码转换相关推荐
- C语言实现gbk/utf8/unicode编码转换
细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4 Unicode与UTF-8互转(C语言实现) 不依赖任何系统API,用c语言实现gbk/utf8/uni ...
- Android原生系统API自带dp、px、sp单位转换
Android系统中自带的Api中可以使用TypedValue进行单位转换 1,调用系统api转换单位 // 获得转换后的px值 float pxDimension = TypedValue.appl ...
- java 拉丁文 unicode_“java语言使用的是Unicode编码”是指的jvm?.java文件?
*.java (utf-8/gbk/...) -> *.class (utf-8) -> memory (utf-16) javac 编译中有参数可以制定源代码的编码-encoding S ...
- python编程语言转换_Python语言 编码转换与中文处理
本文主要向大家介绍了Python语言 编码转换与中文处理,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助. Python 编码转换与中文处理python 中的 unicode是让人很 ...
- Unicode编码与C语言宽字符
文章目录 1.ASCII.ANSI.Unicode都是什么? 2.为什么需要宽字符? 3.C语言如何处理宽字符? 4.Windows中的字符串函数 1.ASCII.ANSI.Unicode都是什么? ...
- Windows系统中搭建Go语言开发环境详解
目录 1.Go语言简介 2.安装Git 3.Go 工具链(编译器)安装 3.1.环境变量GOROOT 3.2.环境变量GOPATH 3.3.Go常用命令 4.包管理 4.1.go module 4.2 ...
- java sql封装,在Java系统中封装SQL语言的处理方法及系统的制作方法
在Java系统中封装SQL语言的处理方法及系统的制作方法[ 技术领域: ][0001]本发明涉及计算机数据处理 技术领域: ,特别是涉及一种在Java系统中封装SQL语言的处理方法及系统.[ 背景技术 ...
- linux sdk 窗口句柄,Venus: 针对Linux平台上,对常用的系统API进行面向对象的封装SDK。...
Venus 项目介绍 Linux平台上,对常用的系统API进行面向对象的封装SDK,使用C++实现,没有使用C++11特效,支持CentOS.Ubuntu.RedHat各个发行版本和不同内核版本使用, ...
- 《CUDA高性能并行计算》----2.2 需要知道的CUDA API和C语言拓展
本 节 书 摘 来 自 华 章 出 版 社 <CUDA高性能并行计算> 一 书 中 的 第2章,第2.2节, 作 者 CUDA for Engineers: An Introduction ...
最新文章
- SAP MM 事务代码MI31之思考之续集
- Oracle 12c 简单的jdbc使用
- K8S部署工具:KubeOperator安装部署
- 悲观锁和乐观锁_悲观锁和乐观锁处理并发操作
- Windows上编译libpng
- 题解 P5259【欧稳欧再次学车】
- [No00009E]几种常见的命名规则
- 腾达无线路由器如何开启无线中继功能
- turtle fillcolor_Python编程:使用海龟turtle画图制作可爱的哆啦A梦,你也可以的。
- Smart3D三维建模操作笔记
- OA系统如何快速做出统计报表
- 惊艳!用 Python 送女神们别样的礼物!
- 985高校硕导跳槽高中当老师,博士扎堆中小学,是内卷还是进步?
- 使用ember-simple-auth实现Ember.js应用的权限控制
- 一元四次方程的求根公式
- Vin码车架号识别技术已经很成熟了
- 星星之火OIer:编程社四连测总结
- Vue动态循环背景图片
- ffmpeg使用filter生成H264测试视频(带时间戳OSD)
- 经典的足球明星广告--[困兽斗]
热门文章
- RecursiveTask和RecursiveAction的使用 以及java 8 并行流和顺序流
- 人,人生,人类,思考
- vue_prop注册及验证
- CommonJS概述及使用
- 9行代码AC_HDU-6374 Decimal(余数,因子)
- python opencv图片放大 缩小_Python OpenCV之图片缩放的实现(cv2.resize)
- 在python中定义类时、运算符重载_python自定义类运算符重载
- ntfs分配单元大小怎么选_星月菩提尺寸大小怎么选
- mysql中获取时间的年月日_关于苹果ios中的Date()获取时间NaN的问题
- 网络服务器安全协议,ipsec 网络安全协议