现在的位置: 首页 > 综合 > 正文

UCS-2与UTF8之间的选择(2)–Unicode组织提供的C/C++的Unicode编码转换函数

2012年02月14日 ⁄ 综合 ⁄ 共 3038字 ⁄ 字号 评论关闭

UCS-2UTF8之间的选择(2--Unicode组织提供的C/C++Unicode编码转换函数

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

讨论新闻组及文件

这里我大概搜索到了3个库,一个是Unicode组织自己提供的,一个是IBM做的开源ICU工程中的,一个是开源的UCData 2.9

但是UCData2.9中并没有UTF-16,通篇都是为UTF-32设计的,属于那种将来可能会用的到的库,因为目前WindowsLinux的内核都还没有UTF-32化,注定假如使用UTF-32将会在两个地方都失去性能优势。

于是剩下的两个选择就很有意思了,一个是Unicode自己提供的那几个简单的转换函数,一个是IBM提供的一个巨无霸的库,一个Unicode的相关库到了10M的确算是很夸张的了,难怪被别人称作蓝色巨人,干什么都是大手笔,就像它出品的软件工程软件一样,哪一个都是出手不凡,一出一个系列,每个都大的要命。感叹。。。。。

 

C/C++的库的角度,我就只查看这两个了。

Unicode组织的函数:(甚至不能称作库)

这些函数很好用,并且自带了测试套件。

windows中,新建一个空的工程,并将ConvertUTF.h,CVTUTF7.h,CVTUTF7.C,harness.c添加到工程中,编译,运行,既可以运行测试例程,utf7这个我们一般用不上,其实也可以不添加。在我的VS2005 SP1中,运行结果如下:

Three tests of round-trip conversions will be performed.

One test of illegal UTF-32 will be peroformed.

Two illegal result messages are expected; one in test 02A; one in test 03A.

These are for tests of Surrogate conversion.

 

Begin Test01

******** Test01 succeeded without error. ********

 

Begin Test02

Test02A for 55296, input 0000d800, output 0000,0000, result 3

!!! Test02A: note expected illegal result for 0x0000D800

******** Test02 succeeded without error. ********

 

Begin Test03

sourceIllegal   Test03A for 55296 (0xd800); output ; result 3

!!! Test03A: note expected illegal result for 0x0000D800

******** Test03 succeeded without error. ********

 

Begin Test04

******** Test04 succeeded without error. ********

 

很显然的4个测试全部通过,没有任何错误。

提供的我们可能需要的函数有:

isLegalUTF8Sequence()判断一个字符串是否是合法的UTF8字符串

ConvertUTF8toUTF16()转换UTF8字符串到UTF16

ConvertUTF16toUTF8()转换UTF16字符串到UTF8

原型:

ConversionResult ConvertUTF8toUTF16 (

       const UTF8** sourceStart, const UTF8* sourceEnd,

       UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);

 

ConversionResult ConvertUTF16toUTF8 (

       const UTF16** sourceStart, const UTF16* sourceEnd,

       UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);

所有的函数采取的结尾判断方式是传递一个结束的指针位置,而不是常见的长度。

 

其提供的几个宏也很有用:

typedef unsigned long    UTF32; /* at least 32 bits */

typedef unsigned short   UTF16; /* at least 16 bits */

typedef unsigned char    UTF8;  /* typically 8 bits */

typedef unsigned char    Boolean; /* 0 or 1 */

 

BooleanC++中似乎是不怎么需要.

 

/* Some fundamental constants */

#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD

#define UNI_MAX_BMP (UTF32)0x0000FFFF

#define UNI_MAX_UTF16 (UTF32)0x0010FFFF

#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF

#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF

 

很有价值的几个宏,除了都强制转换为UTF32比较郁闷,UNI_MAX_BMPUNI_MAX_UTF16可以用的上。

 

typedef enum {

    conversionOK,        /* conversion successful */

    sourceExhausted,  /* partial character in source, but hit end */

    targetExhausted,  /* insuff. room in target for conversion */

    sourceIllegal     /* source sequence is illegal/malformed */

} ConversionResult;

 

这是上述那几个函数的返回值,英文注释解释的很清楚了。

 

typedef enum {

    strictConversion = 0,

    lenientConversion

} ConversionFlags;

 

这是那几个函数的第五参数,一个表示严格转换,一个表示宽容的转换

 

排除harness.c,不编译,添加ConvertUTF.c,自己制作一个测试:

 

// Unicode.cpp : 定义控制台应用程序的入口点。

//

#include <stdio.h>

#include <tchar.h>

#include <windows.h>

#include "ConvertUTF.h"

 

int _tmain(int argc, _TCHAR* argv[])

{

    ConversionResult result = sourceIllegal;

    UTF16 utf16_buf[8] = {0};

    utf16_buf[0] = 0xd834;

    utf16_buf[1] = 0xdf00;

    utf16_buf[2] = 0xd834;

    utf16_buf[3] = 0xdf01;

    utf16_buf[4] = 0xd834;

    utf16_buf[5] = 0xdf02;

    utf16_buf[6] = 0;

    utf16_buf[7] = 0;

    UTF16 *utf16Start

抱歉!评论已关闭.