UTF-8编码实测
来源:互联网 发布:淘宝详情页制作软件 编辑:程序博客网 时间:2024/06/06 01:30
本文打算用C++程序跟踪UTF-8字符的二进制格式。从实践上感受一下UTF-8的应用。
开发环境是UBuntu12.04 32bit OS. GCC 4.6.3,系统字节顺序是little endian.
如果有汉字‘一’,首先通过一个网站工具:http://rishida.net/tools/conversion/ 可以查到它的Unicode码是:0x4E00
用UTF-8对0x4E00进行编码后是:E4 B8 80,三字节。
下面的代码用来打印二进制码:
#include "test.h"#include "util/endian.h"#include "util/utf.h"#include <iostream>using namespace std;int main(int argc, char ** argv) { // TEST(3 > 2); char const * p = "一"; cout << PrintStringAsBinaryString(p) << endl; string str = "一"; cout << PrintStringAsBinaryString(str) << endl; cout << IsLittleEndian() << endl;}
utf.h中的两个函数实现代码:
#ifndef UTIL_UTF_H_#define UTIL_UTF_H_#include "util/endian.h"string PrintStringAsBinaryString(char const* p) { stringstream stream; for (size_t i = 0; i < strlen(p); ++i) { stream << PrintIntAsBinaryString(p[i]); stream << " "; } return stream.str();}string PrintStringAsBinaryString(string const& str) { stringstream stream; for (size_t i = 0; i < str.size(); ++i) { stream << PrintIntAsBinaryString(str[i]); stream << " "; } return stream.str();}#endif
// T must be one of integer typetemplate<class T>string PrintIntAsBinaryString(T v) { stringstream stream; int i = sizeof(T) * 8 - 1; while (i >= 0) { stream << Bit_Value(v, i); --i; } return stream.str();}
// Get the bit value specified by the index// index starts with 0template<class T>int Bit_Value(T value, uint8_t index) { return (value & (1 << index)) == 0 ? 0 : 1;}显示结果是:
11100100 10111000 10000000刚好是E4 B8 80
这里可以看到Leading byte就是最高位的字节E4, 就存放在char const * p所指的的内存的起始地址,因此可以看出是Big endian,也就是在系统中实测默认应该采用的是UTF-8 BE编码。
下面继续奋战,把UTF-8转换成Unicode码,也就是code point。注意code_point类型的定义
typedef uint32_t code_point
现在测试代码修改一下,引入boost::locale库,这个算法自己也可以写,不过时间紧张,先用成熟的库吧。
#include "test.h"#include "util/endian.h"#include "util/utf.h"#include <iostream>#include <boost/locale/utf.hpp>using namespace std;using namespace boost::locale::utf;int main(int argc, char ** argv) { // TEST(3 > 2); char const * p = "一"; cout << PrintStringAsBinaryString(p) << endl; string str = "一"; cout << PrintStringAsBinaryString(str) << endl; code_point c = utf_traits<char, sizeof(char)>::decode(p, p + 3); cout << "code point: 0x" << std::hex << c << " binary format:B" << PrintIntAsBinaryString(c) << endl;}倒数第二行代码就是调用了decode进行解码。
结果是:
code point: 0x4e00 binary format:B00000000000000000100111000000000
非常理想。也可以传递string::iterator作为参数,只是注意string::begin()不能直接作为参数使用,而要像这样:
string::iterator itor = str.begin();utf_traits<char, sizeof(char)>::decode(itor, str.end());因为decode的第一个参数是引用,decode内部会执行++操作。而string::begin()是不允许改变的,因此编译会报错。
- UTF-8编码实测
- UTF-8 编码介绍
- UTF-8编码规则
- UTF-8 编码
- UTF-8编码研究
- UTF-8编码规则
- 关于UTF-8编码
- 关于UTF-8编码
- UTF-8编码问题
- utf-8编码规则
- UTF-8编码规则
- UTF-8编码规则
- utf-8编码
- UTF-8编码原理
- UTF-8编码
- UTF-8 编码
- emacs utf-8编码
- UTF-8编码规则
- 让你的应用支持新iPad的Retina显示屏
- C#实现程序的版本自动升级更新
- UVA 10128 Queue
- 绑定jndi并载入数据源
- QueryPerformanceCounter
- UTF-8编码实测
- 四则运算之逻辑组合运算
- 树分类,无限极分类
- UniCode下CString 转Char*
- mybatis入门实例
- 一个Java程序员应该掌握的10项技能
- 用C#实现在线升级
- 将excel文件中的数据导入导出至SQL数据库中(Microsoft.Jet.OLEDB.4.0和Microsoft.ACE.OLEDB.12.0|office2003和office2007)
- x264常用options整理