PB对Unicode的支持

PB对Unicode的支持  

1.1 对Unicode的支持

以下是PB8.02的一个例子,大家可以看到调试状态下字符串a得到的是带有半个汉字的字符串,而name的长度也变为了6,说明len函数是把汉字当双字节处理,而英文字母作为单字节来处理的。这样一来,当字符中带有汉字时,字符处理函数(包括mid,right)都会出现长度与字符数不一致的情况。
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!   PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
PB8.02图-1                             PB11.2图-2

然而这种情况在pb11.2中得到了解决,无论是汉字还是英文字母都是被统一的当作一个字符处理,这就是国际上通用的字符编码Unicode。这种编码将世界各国不同的文字字符统一以一个字符看待,而每个字符占两个字节。这样的处理是要付出代价的,但凡用到Unicode的所有字符,都以两个字节处理了,比以前的单字节多占了一个字节的空间。然而这种付出是值得的,它的价值显而易见,消除了各种言语文字集之间处理上的不一致性。这也应该称得上是一种全球化吧。呵呵!

回顾下PB9时代,出现了LeftA、LenA;LeftW、LenW等等,这样的函数形式,是为了解决亚洲字符集(包括了ANSI在内的ASCII字符,即值为0-255之间的单字节编码方式的字符)的处理而增加进来的。带“A”的用于处理单字节,而带“W”的用于处理双字节。当然现在有了Unicode的出现,带“W”的函数已经被废弃了。所以建议大家在以后的编程中不要再去用这些函数,这些函数之所有还保留,只是为了兼容以前pb9版本开发的程序而存在的。而带“A”仍然可以作为处理单字节字符用。下图是PB11.2中对带“W”函数的帮助说明。

PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!

从下图中可以看出三种不同函数形式的处理结果。在PB11.2中常规函数(left、len等)已经可以完全处理双字符,所以带“W”将要被废弃是完全有必要的。然而单字节函数(带“A”)仍就按单字节处理,并且比PB8.02时更能有效的识别单双字节混合的字符串。

PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!

另外PB11.2对Unicode的支持可以通过一个例子看出来,对VC++写的一个API的调用,API函数原型为:

int foo(char *ip)

在PB8.02和PB11.2中调用结果图分别如下:
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力! PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!

图1                                图2

定义和调用都是相同的,分别如下:

   
1 PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力! Function uLong foo (ref String ipaddress) Library "GetIP.dll"
2 PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
3 PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!string   ls_HostIP = space ( 128 )
4 PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力! if foo (ls_HostIP) = 0 then
5 PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!     sle_2. text = trim(ls_HostIP)
6 PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力! end if
7 PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
  

VC++编写的API函数带char*指针带回的是一个单字节字符指针,由上两张图可以看出,PB8.02的字符串是以单字节处理的,它不支持Unicode的;而PB11.2已经支持Unicode了,它把所有的String当Unicode字符处理,故会出现上图的乱码。

当把PB11.2中原来的定义后加上ANSI后即定义为:
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力! Function uLong foo (ref String ipaddress) Library "GetIP.dll" ALIAS FOR "foo;ANSI"
则结果即转化为想要的值了。
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
       

那么PB11.2是如何转化的?

其实这并不是PB所为,而是两种字符集中单个字符所占的字节不同而造成的。我们来看,用LenA()看这个字符的长按理说是为13(实际在PB11.2用lenA函数已经得不出长度了,原因是PB在从API中返回的字符指针时已经把字符串当Unicode处理了),而用len则变为7了。很显然它把每两个节当成了一个Unicode字符。1的十六进制ACSII码为31,9的十六进制ACSII码为39,结合起来就是H31 39,但是字节在内存中的存放都是从右存到左,所以内存就存为H39 31,查看Unicode表可得知是个方框。即本机无此符号字体存在,所以显示不出来,以方框代替了。

注:Unicode表查询

http://www.wiki.cn/wiki/Unicode%E7%BC%96%E7%A0%81%E8%A1%A8/3000-3FFF

PB9以前对字符的解决方法

由于PB9以前没有对Unicode的支持函数,处理再汉字的字符串只能自己写函数处理了。以下给了笔者对len()自己定义了个函数f_mylen()处理带汉字字符串。代码如下:
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力! char l_ch
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
int li_len,li_p
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!string ls_str
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!ls_str
= a_str
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!li_p
= 1
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!do
while len (ls_str) >= li_p
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!     l_ch
= mid(ls_str,li_p, 1 )    
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!    
if asc (l_ch) > 127 then         
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!         li_p
+= 2          
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!    
else         
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!         li_p
+= 1
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!    
end if     
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!     li_len
+= 1
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!loop
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
return li_len

对left()函数做了个自定义f_myleft()代替,代码如下:

PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力! char l_ch
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
int li_len
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!string ls_str
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!string ls_rtn
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!li_len
= f_mylen(a_str)
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
if a_len >= li_len then return a_str
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!ls_str
= a_str
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!li_len
= 1
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!do
while li_len <= a_len and len (ls_str) >= li_len
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!     l_ch
= mid(ls_str,li_len, 1 )    
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!    
if asc (l_ch) > 127 then
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!         ls_rtn
= ls_rtn + mid(ls_str,li_len, 2 )    
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!         li_len
+= 2
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!         a_len
+= 1
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!    
else
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!         ls_rtn
= ls_rtn + mid(ls_str,li_len, 1 )    
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!         li_len
+= 1
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!    
end if     
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!loop
PB对Unicode的支持 - 小伙 - 革命尚未完成,哥还需继续努力!
return ls_rtn
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值