PB對Unicode的支援

來源:互聯網
上載者:User
著作權說明


系列文章在部落格園發表,除允許在互連網上自由轉載外,不允許以其它任何方式拷貝、編輯、印刷出版、製作發行及傳播,包括不允許在筆者未知曉的情況下製作成
各種格式的電子文檔並傳播,更不得在未經筆者本人允許的情況下以任何形式的拷貝用於商業用途。筆者對本系列文章保留有追究其侵權責任的權利。

若需製成電子文檔並用於非商業用途方式的傳播,請保留以下著作權資訊,並與筆者聯絡郵寄副本一份。

作者:張楠

網名:SummerHeart

Email:Costware@163.com

Blog:http://summerheart.cnblogs.com/

      http://blog.csdn.net/summerheart

時間:2008.5.26         

Copyright: 2008  

PS:轉載請保留以上著作權資訊

 

第一章 PowerBuilder不容忽視的細節1. PowerScript

PB的基礎程式設計語言是種被稱之為PowerScript的語言,由PB最先的開發商PowerSoft制定,之所以被稱之為PowerScript,原因是它不同於VB,Delphi、C等語,它自成一套體系,雖然並沒有成為一種標準的程式設計語言而得到廣泛使用,但它在PowerBuilder中卻發揮著無法或缺的做用。下面讓我們看看它的各方面一些特點。

1.1 對Unicode的支援

以下是PB8.02的一個例子,大家可以看到調試狀態下字串a得到的是帶有半個漢字的字串,而name的長度也變為了6,說明len函數是把漢字當雙位元組處理,而英文字母作為單位元組來處理的。這樣一來,當字元中帶有漢字時,字元處理函數(包括mid,right)都會出現長度與字元數不一致的情況。  
  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”函數的協助說明。


 

從中可以看出三種不同函數形式的處理結果。在PB11.2中常規函數(left、len等)已經可以完全處理雙字元,所以帶“W”將要被廢棄是完全有必要的。然而單位元組函數(帶“A”)仍就按單位元組處理,並且比PB8.02時更能有效識別單雙位元組混合的字串。


 

另外PB11.2對Unicode的支援可以通過一個例子看出來,對VC++寫的一個API的調用,API函數原型為:

int foo(char *ip)

在PB8.02和PB11.2中調用結果圖分別如下: 

 

圖1                                圖2

定義和調用都是相同的,分別如下:

   

1Function uLong foo (ref String ipaddress) Library "GetIP.dll"
2
3string  ls_HostIP = space(128) 
4if foo (ls_HostIP) = 0 then
5    sle_2.text=trim(ls_HostIP)
6end if
7

  

VC++編寫的API函數帶char*指標帶回的是一個單位元組字元指標,由上兩張圖可以看出,PB8.02的字串是以單位元組處理的,它不支援Unicode的;而PB11.2已經支援Unicode了,它把所有的String當Unicode字元處理,故會出現的亂碼。

當把PB11.2中原來的定義後加上ANSI後即定義為:Function uLong foo (ref String ipaddress) Library "GetIP.dll" ALIAS FOR "foo;ANSI"

 則結果即轉化為想要的值了。

       

那麼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()處理帶漢字字串。代碼如下:

char l_ch
int li_len,li_p
string ls_str

ls_str =a_str
li_p =1

do while len(ls_str)>=li_p
    l_ch = mid(ls_str,li_p,1)    
    if asc(l_ch) >127 then        
        li_p +=2         
    else        
        li_p +=1
    end if    
    li_len+=1
loop
return li_len

 

對left()函數做了個自訂f_myleft()代替,代碼如下:

char l_ch
int li_len
string ls_str
string ls_rtn
li_len = f_mylen(a_str)
if a_len>=li_len then return a_str
ls_str =a_str
li_len =1

do while li_len <= a_len and len(ls_str)>=li_len
    l_ch = mid(ls_str,li_len,1)    
    if asc(l_ch) >127 then
        ls_rtn = ls_rtn + mid(ls_str,li_len,2)    
        li_len +=2 
        a_len+=1
    else
        ls_rtn = ls_rtn + mid(ls_str,li_len,1)    
        li_len +=1
    end if    
loop
return ls_rtn

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.