最後還是不死心,想要在ubuntu下不經過環境設定轉換的方式找出curses對UTF-8的亂碼有一個直接的解決辦法
終於google到幾篇文章
http://crazykevin.com/?p=92
http://my.opera.com/mingfal/blog/show.dml/395261
還有一個英文的(雖然看不懂,但丟到google翻譯倒也知道了個幾分的意思)
http://mail.nl.linux.org/linux-utf8/2004-08/msg00001.html
裏面所提的重點這裡不在贅述,只是我照著做以後發生了一個問題......
setlocale(LC_ALL,"");
這個函數一加到程式裏面就有了"include不進來?"的問題
http://phorum.study-area.org/index.php/topic,52403.0.html
解決方法呢?靠著一點點運氣,一點點經驗跟很多很多的到google大廟內參拜終於找到一個函數庫,這也就是第1點
1.從[系統]-->[管理]-->[synaptic套件管理程式]-->[搜尋]-->搜尋欄位輸入" locale "..搜尋於欄位選擇"描述及名稱"
這時會出來一大堆套件,不過我們要找的是一個"函數庫"所以只找libxxx名稱的套件,而以lib開頭的函數庫也還滿多的,再把目標縮小到有ubuntu標誌的那幾個
於是終於可以看到一個名為 libicu-dev 的函數庫
其實我也看不懂libicu-dev到底是做啥的!?只是看到其描述最後一句.....for unicode...就把他送到google大廟的偏殿google全文翻譯去....嗯...應該就是他沒錯了
然後呢??還是不行呀,拿出一點點經驗跟一點點想像力...很像跟編碼有關的都歸 locale 管的樣子,那麼是否有一個叫作 locale.h 的含引檔呢?
2.加入含引檔 #include <locale.h>
locale既然是一個在系統下的命令,那他也就是一個程式?既然是一個程式,那他就有可能有一個函數庫可供使用,函數庫..這都要有一個含引檔吧!
而以命名習慣來說你再給人亂取一通不是在找麻煩嘛XD.....(後面這句自己亂加的當沒看到吧XD)
如果第1.沒做直接做這裡說不定也是可以的,只是我所安裝的ubuntu8.04的版本算是一個"很乾淨"的版本,所以一些程式開發的東西可能都還要抓才可以
好了!由上面google到的3篇文章來說可以知道幾個訊息... curses 與 ncurses 是不同的函數庫,而可以處理UTF-8碼的函數庫名稱叫作 ncursesw 所以了
3.原來的#include <curses.h> 或 #include <ncurses.h> 要改成 #include <ncursesw.h> 或是 #include <ncursesw/ncurses.h>
至於該改成怎樣這就要看在您的系統下ncursesw到底是怎麼樣子的,比如我用檔案瀏覽器的搜尋功能去找 ncursesw 他有找到一個資料夾
名字剛好就是ncursesw(不過為何檔案瀏覽器沒辦法顯示點選物件的路徑呀?)所以我的是#include <ncursesw/ncurses.h>
然後在編譯指令也必須聯結到這一個ncursesw
4.原來的編譯指令gcc ..... -lcurses 或 gcc ..... -lncurses 則改成 gcc ..... -lncursesw 表示我們要聯結的是支援UTF-8的ncursesw函數庫不是curses也不是ncurses
xxx.h有可能會因為寫作技巧的關係讓我們叫用curses.h,ncurses.h,ncursesw.h都是一樣的(不過我沒試過,有興趣可以試一下),而且在英文的那個文件
看起來的意思(本人英文很差只能靠google翻出來2266的中文來猜)也是說ncursesw是專為UTF-8寫的一個函數庫所以這一步驟是滿重要的
還有在我實際使用時有一點也是覺得滿重要的
5.在初始化curses函數庫的 initscr() 前必須先叫用 setlocale(LC_ALL,"") 函數,順序不可以弄反了
其實這個也不算重點,就是一個邏輯上的關係而已,只是如果不提出來,又剛好死不死的就是弄錯順序了.那老是在抓前面4個點的錯誤....這不是很冤嗎^^!
最後有一點注意的,就是utf-8的編碼方式是不定長度的,也就是說編出來的一份文件不再是一個英數字型是1Byte一個中文字是2Byte的
這是我昨天寫來算一份文件(字串)要對應到螢幕上座標位置的片段
for(n=0,y=dspy;n<size;y++)
{
for(bt=128,byt=0;bt>1;(bt/=2),byt++)/*求出這個utf-8編碼共佔多少Byte*/
if(!(*(str+n) & bt))
break;
}
而這兩個函數是昨天想自行重組utf-8後丟進curses的觀察用工具(結果當然是失敗做收啦>"<),不過滿有趣的,跟危機百科的utf-8
http://zh.wikipedia.org/wiki/UTF-8
相互對照一下,看看倒底UTF-8都在編些啥東東@@!
/*顯示字串*str共size位元每一個Byte的Bit狀態主要是察看utf-8的狀態*/
int lee_utf8bitdsp(char *str,int size,int dspx,int dspy)
{
int i,n,b,x,y,bt,byt;
for(n=0,y=dspy;n<size;y++)
{
for(bt=128,byt=0;bt>1;(bt/=2),byt++)/*求出這個utf-8編碼共佔多少Byte*/
if(!(*(str+n) & bt))
break;
if(byt<1)
{
lee_bitdsp(str+n,1,dspx,y);
n+=1;
}
else
{
lee_bitdsp(str+n,byt,dspx,y);
n+=byt;
}
}
refresh();
}
/*將從*ptr開始的位置共len個Byte的每一Bit狀態顯示出來*/
int lee_bitdsp(char *ptr,int len,int dspx,int dspy)
{
int i,x,b;
for(i=0,x=dspx;i<len;i++)
{
for(b=128;b>0;(b/=2),x++)
{
if((*(ptr+i) & b))
mvprintw(dspy,x,"1");
else
mvprintw(dspy,x,"0");
}
if(len>1)
{
mvprintw(dspy,x,",");
x+=1;
}
}
}
想說有個setlocale()相對的應該會有getlocale()才對!?
結果並沒有=.=
後來在locale.h中看到setlocale()的函數原型
extern char *setlocale (int __category, __const char *__locale) __THROW;
原來這一個函數的返回值是一個*char
char *tmp;
tmp=setlocal(LC_ALL,"");
printf("tmp=%s \n",tmp);
執行結果
tmp=zh_TW.UTF-8
看來這個函數雖名為set但其實也有做get的動作^^ 本來以為
char *tmp;
tmp=setlocal(LC_ALL,"");
printf("tmp=%s \n",tmp);
必須將tmp給free()掉,結果反而發生記憶體溢位(剛測出來),所以多次叫用時千萬不要在函數內將tmp給free()掉
============================================================================================
2008.07.19補充:
剛灌好的ubuntu8.04所要下載的函數庫
libc6-dev 以此為關鍵字讓套件管理程式做搜尋只出來一個套件,這應該是標準函數庫,如無該函數庫則最簡單的hi程式都無法做編譯
ncursesw 這是支援utf-8的curses函數庫,以此為關鍵字讓套件管理程式做搜尋時共出來3個但內定只有一個是有被安裝的,以-dbg與-dev結尾的未被安裝(都裝起來吧)
libicu-dev 以此為關鍵字讓套件管理程式做搜尋只出來一個套件,這就是locale所需的函數庫了
locale函數庫中關於該編碼所在地的貨幣及數字(應指小數點及進位分隔符號如千位以'號分隔)訊息
可以用localeconv()函數取得
aaa()
{
struct lconv *lcv;
lcv=localeconv();
printf("symbo=%s symbol=%s \n",lcv->int_curr_symbol,lcv->currency_symbol);
}
執行結果:
symbo=TWD symbol=NT$
而更詳細lconv結構則以檔案搜尋找到locale.h內有宣告該結構原型
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。