Folder:
zr (reduce):open all folder
zm (more):close all folder
zo (open):open folder
zc (close):close folder
r, m, o, c 如果用大寫取代,則是代表會用recursive的方式將folder下的folder也執行這個動作。
視窗切換:
ctrl w + 上下左右:代表切換到相對應的上下左右的視窗
尋找:
/keyword:向下尋找keyword
?keyword:向上尋找keyword
n:正向尋找下一個 (原本向下就繼續向下找,向上就向上找)
N:反向尋找下一個
qa:關閉所有window
參考資料 :
大家來學 Vim 一個歷久彌新的編輯器
2008年8月15日 星期五
| [+/-] |
[Vim] Folder, 視窗切換, 尋找關鍵字 |
| [+/-] |
[Python] 字串的編碼 |
在Python裡面的處理主要是以UTF-8的方式來處理字串,所以在抓一些繁體中文的文字檔時,要先把他轉成UTF-8的形式。
轉換的方式為:
try:
utf8_string = unicode(cp950_string, "cp950").encode("utf8")
except:
print "can't transfer"
做法大致上是先把字串用unicode這個function decode成unicode的形式,再用encode這個function轉成你想要轉的編碼。
這裡的例子是將繁體中文轉成utf8,而編碼使用cp950是因為它支援一些big5沒有支援的繁體中文字。
如果沒辦法將編碼轉成unicode的情況,會產生expection,如果不catch的話程式會中止。在這裡很簡單的印出錯誤訊息。
參考資料 :
http://hoamon.blogspot.com/2008/05/python-big5.html
2008年8月13日 星期三
| [+/-] |
[Unix] setenv Memory Leak的問題 |
最近為了程式自己會莫名其妙的長大而苦惱,但是去看code卻也沒有發現什麼忘記delete或是free的pointer。本來為了避免這些麻煩,所以大部分的資料都是用string或是stl的container來實作,沒想到還是遇到這樣的問題。
把code翻了又翻,最後幾乎把所有可能發生的function call 都加上memory leak去google搜尋,結果發現了下面的man page,告訴我們說如果setenv被連續使用時,set的value長度不一樣,他會自己重新malloc一個新的記憶體,舊的記憶體就會造成memory leak了。
居然和系統(OpenBSD)上面的man page寫的不一樣,如果沒有用google search的話,我大概還在找到死吧。只能說不經一bug,不長一智...QQ。
參考資料 :
http://www.manpagez.com/man/3/setenv/
2008年8月1日 星期五
| [+/-] |
[C++] class member function使用template注意事項 |
在寫一個class的時候,大多習慣把prototype放在.h檔,而定義則放在.cpp檔。
但是當你的member function有使用template時,如果把定義還是放在.cpp檔中,
在link的時候會出現unresolved external symbol,也就是找不到這個function。
所以必須要把這些有用template的function也放在.h檔裡面定義,這樣template就可以正確產生
不同type的function instances。
參考資料 :
http://bytes.com/forum/thread165359.html
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.7
2008年7月25日 星期五
| [+/-] |
[vim] 自訂專案開啟 (project.vim taglist.vim) |
在程式寫很大的時候,常常要編輯很多檔案。雖然名字取的好可以幫助記憶,但是還是需要輸入很多指令來切換編輯檔案。
下面的方式就是用一些vim的plugin,來達到輕鬆的專案開啟以及管理。也能夠很容易的做trace code的動作。
要達要目標我們需要2個vim plugins
1. taglist
2. project
taglist
source code browser,用來方便瀏覽各種語言的原始碼。配合ctags所產生的tags,能跳到variable和function的所在位址。
設定:
1. 確認ctags為Exuberant ctags 5.0以上,vim版本要6.0以上。
2. 安裝taglist.vim這個plugin
3. 在.vimrc設定
nnoremap
nnoremap
project.vim
產生一個project的檔案瀏覽器。
設定:
1. 安裝project.vim
2. 在.vimrc設定
" Open default Project (in ~/.vimprojects)
nnoremap
" taglist 執行的ctags的路徑, 在這裡安裝在家目錄底下
let Tlist_Ctags_Cmd='~/bin/ctags'
" 自動更新tags
function UPDATE_TAGS()
call system("ctags -R")
endfunction
autocmd BufWrite,BufWritePost *.cpp,*.h,*.c :call UPDATE_TAGS()
3. 設定.profile (.cshrc)
for .profile
alias openproj='ctags -R;vim +Project'
for .cshrc
alias openproj 'ctags -R;vim +Project'
使用方法:
在專案的目錄下(source code存放的目錄),輸入
$openproj
開啟檔案,第一次要在project的視窗裡面做設定。
在project視窗輸入'\C'
根據出現的提示做設定
Enter the Name of the Entry: MyProject #專案名稱
Enter the Absolute Directory to Load:/home/powentan/project #專案絕對路徑
Enter the CD parameter:#輸入enter
Enter the File Filter: *.cpp *.h #要加入專案的檔案格式
設定好了以後會產生叫做~/.vimprojects存放你的專案設定,之後再用openproj開啟檔案時,就會自動load專案設定檔。
開好專案以後,選取空白的視窗,按下
產生好了以後按
利用project browser (project.vim)跟source code browser (taglist.vim),我們就能很方便的進行code的修改和trace。
參考資料 :
Using vim as an IDE all in one
vim: lightning fast navigation in a large software project
2008年7月24日 星期四
| [+/-] |
[google] google bookmark的使用 |
目前使用的網路書籤為google bookmark,配合上firefox的GMarks這個plugin,在瀏覽和管理上都相當的方便。GMark可以在側欄開啟,比起在menubar上面好用很多。在IE 6.0上面使用menubar來瀏覽書籤移動會變的卡卡的不好用,用側欄開啟就沒有這個困擾。
另外google bookmark還能在google notebook裡面瀏覽和編輯,增加了很多方便性。
還有匯出的功能,這樣就算不用google bookmark也不怕因為書籤被綁死還無法使用其他服務,在這點google的"Don't be evil"還算蠻好的。
在使用書籤要注意的一點是,如果一個書籤有好幾個tags,而只要刪除其中的一些tags,要使用移除分類標籤這個功能,而不是使用刪除。如果用刪除的話,整個書籤就會完全被刪除,唯一補救的方法就是在google notebook裡面的垃圾桶救回。
2008年7月15日 星期二
| [+/-] |
[Unix] 轉換不同時區的時間 |
轉換不同地方的時間因為有些地區的夏季時間(day light saving time)不同,所以不能只用和GMT
的差距來計算,還要知道夏季時間差、開始以及結束,非常不方便。
因此使用環境變數"TZ"來設定系統的時間,只要知道那個地區的time zone string就能方便的進行轉換。
time zone string在系統的位址為 /usr/share/zoneinfo 底下的檔案和資料夾就是代表各地區的time zone string。
例如:台北的為Asia/Taipei,是在Asia資料夾底下的Taipei檔案,而英國倫敦則是Europe/London。
在shell底下只要用下面的指令就可以把目前系統時間轉換成當地時間:
for ksh:
$TZ="Europe/London";export TZ
for csh:
$setenv TZ "Europe/London"
而在C程式裡面則是呼叫setenv這個function:
setenv("TZ", "Europe/London", 1);
在不同地方時間的轉換則是用下面的方法:
1. 取得source地區的系統時間
2. 轉換到destination的時區
3. 利用source地區的系統時間,經由localtime轉變成destination的struct tm時間。
參考資料 :
| [+/-] |
[Socket] 用Multicast來傳輸資料 |
unicast, multicast, broadcast 介紹三種的網路傳輸方式。
其中 Multicast 是用廣播的方式,將資料傳送給所有加入群組的 ip。
IP區段為:224.0.0.0 ~ 239.255.255.255
下面介紹如何設定傳送和接收 Multicast的 Socket。
標頭檔:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <err.h>
#define PORT 6000
#define GROUP_IP "224.0.0.1"
1. 首先產生一個socket,設定為datagram
sock = socket(AF_INET, SOCK_DGRAM, 0);
2. 設定sockaddr
struct sockaddr_in addr;
bzero(&addr, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(GROUP_IP); //傳送要設定傳送的multicast ip
//接收則是要將ip設定成INADDR_ANY
//透過bind來接收multicast資料
addr.sin_port = htons(PORT);
3. 接收設定資料要進行bind和設定multicast addr
addr.sin_addr.s_addr = inet_addr(INADDR_ANY);
//bind
if (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) < 0)
{
perror("bind");
exit(1);
}
mreq.imr_multiaddr.s_addr = inet_addr(GROUP_IP);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq)) < 0)
{
perror("setsockopt mreq:");
printf("%d %s\n", errno, strerror(errno));
exit(1);
}
4. 傳送和接收
傳送:
sendto(sock, buf, bufLen, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr));
接收:
u_int addrLen = sizeof(struct sockaddr);
recvfrom(sock, buf, bufLen, 0, (struct sockaddr *)&addr, &addrLen);
參考資料 :
unicast, multicast, broadcast - http://www.hoyo.idv.tw/hoyoweb/document/view.php?sid=109&author=hoyo&status=view
2008年7月8日 星期二
| [+/-] |
[Vim] Class Browser : Taglist |
taglist是一個vim的class browser plugin,它能讓vim編寫程式更方便。
設定方式:
1. exuberant ctags 版本要在5.0以上
2. 下載taglist
3. 如果沒有建立過vim的plugin,要建立~/.vim,以及~/.vim/plugin這兩個目錄
4. 把taglist解壓縮,把裡面的 plugin/taglist.vim複製到 ~/.vim/plugin底下
5. 在.vimrc裡面加入 nnoremap <silent> <F8>
以上設定完畢,只要在進入vim時按F8,就能把這個檔案的class browse顯示在視窗左邊。
如果要一次開啟整個資料夾,也可以用以下的方法:
:TlistAddFilesRecursive /my/project/dir *.c
這樣就能一次把/my/project/dir 底下的所有.c檔匯入。
TlistAddFilesRecursive是把目錄底下的所有檔案以遞回方式全部載入,而TlistAddFiles則只載入這個目錄底下的檔案。
參考資料 :
Taglists plugin for Vim - http://bubudog.blogspot.com/2007/01/taglists-plugin-for-vim.html
2008年7月1日 星期二
| [+/-] |
wxPython : 能改變顏色的文字編輯區塊StyledTextCtrl |
我們在編輯程式的編輯器中,顯示程式碼的區塊能根據不同語言的程式關鍵字而變色。
這樣的編輯區塊在wxPython裡面也有。
wx.stc.StyledTextCtrl:由Scintilla這個open source的編輯套件移植過來的,可以設定一些和編輯器相關的設定。
stc = wx.stc
stc.SetText(text) #設定string text到editor中
stc.SetKeyWords(keywordset, keywords) #設定editor的keyword
stc.SetCurrentPos(pos) #設定目前的位址
用這個元件我們就可以實作出屬於自己的editor。
參考資料 :
StyledTextCtrl - http://www.wxpython.org/docs/api/wx.stc.StyledTextCtrl-class.html
2008年6月27日 星期五
| [+/-] |
gdb的一些常用指令 |
backtrace(bt):顯示程式目前的stack狀態,用於檢查dump core很方便。
frame #:配合backtrace的結果,選擇要跳到的stack #,就可以檢查某個stack的狀態。
在多個source files裡面跳到其他file:list filename:1,用來跳到filename這個檔案的第一行。
用 list 也可以跳到某個檔案的某個function,list filename:function。
參考資料 :
http://www.study-area.org/cyril/opentools/opentools/x1253.html
| [+/-] |
Google App Engine |
如何利用Google App Engine來建立自己的Web Service:
http://blog.pixnet.net/jacklin0508/post/16272390
Google App Engine的 Tutorial:
http://code.google.com/appengine/docs/gettingstarted/
jQuery:Javascript Library
http://jquery.com/
django:Python Web Framework
http://www.djangoproject.com/
http://www.openfoundry.org/index.php?option=com_content&Itemid=144&id=1330&lang=en&task=view
參考資料 :
http://blog.pixnet.net/jacklin0508/post/16272390
2008年6月24日 星期二
| [+/-] |
[Python] 字串處理, 檔案讀取, 系統參數, Trace目錄 |
Python 字串處理:
return value
切token : str.split(delimiter) list
找字尾 : str.endswith(endString) bool (有沒有找到)
找字首: str.startswith(startString) bool (有沒有找到)
找子字串 : str.find(subString) 子字串的開頭位址
去空白 : str.strip() string
Regular expression:
re.search(regex, subject)
re.match(regex, subject)
re.findall(regex, subject)
re.finditer(regex, subject)
re.sub(regex, replacement, subject)
re.split(regex, subject)
re.complie(regex, subject)
檔案處理:
fp = open(file, "r") #讀檔
fileString = fp.read() #把整個檔案讀入buffer
fileLines = fp.readlines() #把整個檔案以一行一行形式讀入list
執行參數:
import sys
sys.argv #參數個數
sys.argv[1] #第1個參數
Trace 目錄:
import os, sys
from stat import *
def walktree(top, callback):
'''recursively descend the directory tree rooted at top,
calling the callback function for each regular file'''
for f in os.listdir(top):
pathname = os.path.join(top, f)
mode = os.stat(pathname)[ST_MODE]
if S_ISDIR(mode):
# It's a directory, recurse into it
walktree(pathname, callback)
elif S_ISREG(mode):
# It's a file, call the callback function
callback(pathname)
else:
# Unknown file type, print a message
print 'Skipping %s' % pathname
def visitfile(file):
print 'visiting', file
if __name__ == '__main__':
walktree(sys.argv[1], visitfile)
參考資料:
Python's re Module
stat -- Interpreting stat() results
Common string operations
Python Library Reference
2008年6月19日 星期四
| [+/-] |
Firefox 3.0 |
最新版本的Firefox比起之前的版本有以下的感覺:
1. 速度有變快
2. 附加元件管理員變的比較好
3. 書籤組織功能加強
Firefox一些好用的Plugins:
1. google toolbar:整合google的工具在 firefox 的 toolbar 上面。
2. GMark:專門使用 google 書籤 的 plugin,介面跟編輯有比原本 google toolbar 上面的好用,重點在於使用 Ubuntu 不會讓書籤無法下載。
3. RefControl:可以對某個網站指定要送的 Referer 是什麼,對於那種不讓站外連圖片的網站(無X),可以達到破解的效果。
4. Clipmarks:可以把一個網頁上的東西切成一塊一塊,並且選擇你想要剪下的部分,傳送到 Clipmarks 的網站。可以用來剪貼網路上面的資訊。
參考資料 :
Mozilla Taiwan 正體中文 - http://www.moztw.org/
2008年6月17日 星期二
| [+/-] |
wxPython中有興趣的widget |
顯示進度 (wx.Gauge):wxPython in Action(五十六)
顯示進度 Dialog (wx.ProgressDialog):wxPython in Action(七十七)
分割視窗 (wx.SplitterWindow) : wx.SplitterWindow
多重版面 (wx.Notebook):wx.Notebook
Wizard (安裝導覽, 教學導覽) (wx.Wizard):wxPython in Action(八十一)
參考資料 :
The wxPython tutorial - http://zetcode.com/wxpython/
wxPyhthon In Action - http://www.pythontik.com/blog/default.asp
2008年6月16日 星期一
| [+/-] |
C : 非固定參數function |
有很多格式化的function,像是 printf,scanf 之類,由於格式不固定,造成後面接的參數個數也不一定。這時候就要用到非固定參數 function 的技巧了。
#include <stdarg>
void print(char *fmt, ...)
{
//宣告一個多參數變數
va_list ap;
//重組的格式
char *nFmt;
//取得多參數變數的初始化
va_start(ap, fmt);
//重組字串的格式 (asprintf 會自動幫buf allocate記憶體)
asprintf(&nFmt, "%s\n", fmt);
//輸出結果到stdout
vfprintf(stdout, nFmt, ap);
//釋放asprintf 自動 allocate的記憶體
free(nFmt);
}
這個function print所做的事情就是把原本要印出的字串格式重組,
最後在後面加個"\n"。
參考資料 :
man va_start
2008年6月13日 星期五
| [+/-] |
libpq : include 和 library 的設定 |
在 shell 下輸入:pg_config --help ,會出現很多 option 可以選擇。
其中 --includedir 是 libpq C header的位置
而 --libdir 是 library的位置
在compile時,把 gcc -I (include dir) 和 -L (library dir) 的 path 設定正確,這樣才不會出現 undeclare 或是 undefined reference 的錯誤產生
參考資料 :
http://www.freebsd.org.hk/html/postgresql/libpq-chapter.htm
| [+/-] |
libpq : 存取PostgreSQL的C API |
我們寫的程式透過 libpq 的 api 可以間接存取 PostgreSQL 裡面的資料。
要對 PostgreSQL 執行一個 SQL Command 步驟分成以下幾步:
1. 連上 PostgreSQL 上的 DB ( conn = PQconnectdb(connStr) )
2. 檢查 PQconnectdb 回傳的狀態 ( PQstatus(conn) == CONNECTION_OK )
3. 執行 SQL Command ( res = PQexec(conn, SQLCmd) )
4. 檢查回傳的 res 是否正常 ( PQresultStatus(res) == PGRES_TUPLES_OK )
5. 取出 res 裡的資料 ( for (i = 0; i < PQntuples(res); i++)
{
PQgetvalue(res, i, 0)
}
)
6. 清除資料 ( PQclear(res) )
7. 和資料庫斷線 (PQfinish(conn))
參考資料 :
C Language Interface (LIBPQ) - http://www.postgresql.org/files/documentation/books/aw_pgsql/node147.html
2008年6月12日 星期四
| [+/-] |
C++ : 如何把class member function當成function pointer傳入 |
將 member function 宣告成 static 就可以傳入。
可是 static member function 不能呼叫this pointer,這樣就失去呼叫 member function 的意義了。解決方法是把在呼叫時,把物件的指標傳入。但是呼叫別人的function時,不能改變參數,所以必須建立一個 global variable 或是 static member variable ,在產生物件的同時,把這個變數設定成物件的 reference ,這樣一來呼叫 static member function 時,就可以利用這個 variable 來呼叫物件的其他東西。
class Obj
{
public:
static void *self; //指向自己的pointer
Obj()
{
Obj::self = this; //指向自己
}
static void WrapperFun() //wrapper function
{
Obj::self->Fun(); //真正要呼叫的member function
}
void Fun()
{
//...
}
};
呼叫時:
some_function(WrapperFun);
這樣就可以達到呼叫我們要呼叫的non-static member function的效果了。
參考資料 :
Executing an Object's Member Function in a Separate Thread - http://gethelp.devx.com/techtips/cpp_pro/10min/10min0800.asp
How to use SetTimer() with callback to a non-static member function - http://www.cppblog.com/leo-chen/archive/2007/05/16/24186.html