九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

UCS-2与UTF8之间的选择(4)--linux中各编码字符串的C/C++输出支持及方式比较


UCS-2UTF8之间的选择(4--linux中各编码字符串的C/C++输出支持及方式比较

write by 九天雁翎(JTianLing) -- www.jtianling.com

讨论新闻组及文件

继续研究UTF8UCS-2的选择,这里继续使用上一次提到的函数。

鉴于大家不一定能找到下载的地址,而源文件是允许自由散发的,我将代码打包,提供给大家下载,下载地址还是在讨论新闻组及文件中,名字为unicodeorg.rar

 

昨天看了下Windows下的方法,这次研究Linux下的:

 1 #include <stdio.h>
 2 #include <locale.h>
 3 #include <stdlib.h>
 4 #include "ConvertUTF.h"
 5
 6 int main(int argc, char* argv[])
 7 {
 8
 9     ConversionResult result = sourceIllegal;
10     UTF16 utf16_buf[3] = {0};
11     utf16_buf[0] = 0x4e2d;
12     utf16_buf[1] = 0x6587;
13     utf16_buf[2] = 0;
14     UTF16 *utf16Start = utf16_buf;
15     UTF8 utf8_buf[12] = {0};
16     UTF8* utf8Start = utf8_buf;
17
18     // If you want to test next line, you can't get anything but ???
19     // wprintf("%s/n", utf16_buf);
20
21     result = ConvertUTF16toUTF8((const UTF16 **) &utf16Start, &(utf16_buf[3]), &utf8Start, &(utf8_buf[12]), strictConversion);
22     switch (result) {
23         default: fprintf(stderr, "Test02B fatal error: result %d for input %08x/n", result, utf16_buf[0]); exit(1);
24         case conversionOK: break;
25         case sourceExhausted: printf("sourceExhausted/t"); exit(0);
26         case targetExhausted: printf("targetExhausted/t"); exit(0);
27         case sourceIllegal: printf("sourceIllegal/t"); exit(0);
28     }
29
30     int i = 0;
31     for(; i < 12; ++i)
32     {
33         printf("%x ", utf8_buf[i]);
34     }
35     
36     printf("/n");
37
38     printf("%s/n", (char*)utf8_buf);
39     bzero(utf16_buf, sizeof(utf16_buf));
40
41     UTF8* utf8End = utf8Start;
42     utf8Start = utf8_buf;
43     utf16Start = utf16_buf;
44
45     result = ConvertUTF8toUTF16((const UTF8 **) &utf8Start, utf8End, &utf16Start, &(utf16_buf[3]), strictConversion);
46     switch (result) {
47         default: fprintf(stderr, "Test02B fatal error: result %d for input %08x/n", result, utf16_buf[0]); exit(1);
48         case conversionOK: break;
49         case sourceExhausted: printf("sourceExhausted/t"); exit(0);
50         case targetExhausted: printf("targetExhausted/t"); exit(0);
51         case sourceIllegal: printf("sourceIllegal/t"); exit(0);
52     }
53
54     // If you want to test next line, you can't get anything
55     wprintf("%s/n", utf16_buf);
56
57     return 0;
58 }
59

 

运行结果:

e4 b8 ad e6 96 87 0 0 0 0 0 0

中文

 

这里和Windows中不同的就是输出UTF-8的字符串在Linux下甚至不需要通过setlocale设置环境变量,这样对于C++的输出估计还是有好处的:),起码不会去影响到C++的正常输出。但是,对于宽字节的输出没有办法成功,就算你像在Windows中设置locale也没有用,道理也很简单,因为Linux下的locale我就是设置成UTF-8-_-!

 

 1 #include <stdio.h>
 2 #include <locale.h>
 3 #include <stdlib.h>
 4 #include <iostream>
 5 #include "ConvertUTF.h"
 6 using namespace std;
 7
 8 int main(int argc, char* argv[])
 9 {
10     ConversionResult result = sourceIllegal;
11     UTF16 utf16_buf[3] = {0};
12     utf16_buf[0] = 0x4e2d;
13     utf16_buf[1] = 0x6587;
14     utf16_buf[2] = 0;
15     UTF16 *utf16Start = utf16_buf;
16     UTF8 utf8_buf[12] = {0};
17     UTF8* utf8Start = utf8_buf;
18
19     result = ConvertUTF16toUTF8((const UTF16 **) &utf16Start, &(utf16_buf[3]), &utf8Start, &(utf8_buf[12]), strictConversion);
20     switch (result) {
21         default: fprintf(stderr, "Test02B fatal error: result %d for input %08x/n", result, utf16_buf[0]); exit(1);
22         case conversionOK: break;
23         case sourceExhausted: printf("sourceExhausted/t"); exit(0);
24         case targetExhausted: printf("targetExhausted/t"); exit(0);
25         case sourceIllegal: printf("sourceIllegal/t"); exit(0);
26     }
27
28     int i = 0;
29     for(; i < 12; ++i)
30     {
31         printf("%x ", utf8_buf[i]);
32     }
33     
34     printf("/n");
35
36     cout << (char*)utf8_buf <<endl;
37     bzero(utf16_buf, sizeof(utf16_buf));
38
39     UTF8* utf8End = utf8Start;
40     utf8Start = utf8_buf;
41     utf16Start = utf16_buf;
42
43     result = ConvertUTF8toUTF16((const UTF8 **) &utf8Start, utf8End, &utf16Start, &(utf16_buf[3]), strictConversion);
44     switch (result) {
45         default: fprintf(stderr, "Test02B fatal error: result %d for input %08x/n", result, utf16_buf[0]); exit(1);
46         case conversionOK: break;
47         case sourceExhausted: printf("sourceExhausted/t"); exit(0);
48         case targetExhausted: printf("targetExhausted/t"); exit(0);
49         case sourceIllegal: printf("sourceIllegal/t"); exit(0);
50     }
51
52     return 0;
53 }
54

 

直接可以获得

e4 b8 ad e6 96 87 0 0 0 0 0 0

中文

的输出,也不需要调用C++locale(imbue)函数去改变流的状态,甚至可以说,使用了UTF-8不仅仅是对ASCII完全的兼容了,对于新添加的字符也是可以不改变任何代码就做到兼容的,这点给我印象深刻。难怪UTF-8虽然是变长的编码方式,但是还是获得了这么广范围的应用。

这样的情况下,在Linux下同时在C C++中使用UTF-8输出中文也不会有任何冲突,这个优势比在Windows下大多了。

另外,有个很重要的问题需要提及的就是,目前我使用的Ubuntu8.04桌面版,不支持全Unicode的编码,似乎中文是没有什么问题,但是以前那几个太玄经的字符是输出不了的,可能其Unicode的支持只到到BMP这一层,这点比Windows稍逊色。以前测试过,的确是输出不了,但是源代码已经被覆盖了,大家可以自己去确定一下:)

 

 

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

分类:  网络技术 
标签:  C++  Linux 

Posted By 九天雁翎 at 九天雁翎的博客 on 2009年03月06日

前一篇: UCS-2与UTF8之间的选择(3)--windows中各编码字符串的C/C++输出支持及方式比较 后一篇: UCS-2与UTF8之间的选择(5)--断然决定UTF-8