strftime是把struct tm時間轉成時間字串的函式,根據你定的format string,function會把產生的字串塞到你的buffer。
strptime是把時間字串根據你指定的format string轉換成struct tm時間。
兩者有相反的功能,但是format string卻不是完全一樣的。
舉例來說:在strftime裡面的 %F (相當於%Y-%m-%d),在strptime卻沒有。因此在使用format string的時候還是要去man一下才能確定是否有這樣的功能。
參考資料 :
man strptime, man strftime
2008年10月17日 星期五
| [+/-] |
[C/C++] strftime 和 strptime的format string |
2008年9月6日 星期六
| [+/-] |
[Vim] 利用ctags找尋函數的tags設定 |
在vim裡面用來找函數定義的時候, 要用ctags產生的對應檔tags來找到位址.
而.vimrc裡面也可以對tags檔的放置位址做設定
像是可以先對所有的C/C++ 系統的.h .c .cpp檔做成一個ctags叫做cpp.tags, 然後在設定時用
set tags=path/cpp.tags來設定要把cpp.tags檔加入搜尋函數定義裡面.
這裡要注意的是, 設定tags和./tags意義是不同的.
tags代表目前vim所在的路徑
./tags代表目前檔案所在路徑
兩者意義是不同的.
因為在vim中開啟檔案可以不用切換到檔案的路徑下, 所以如果要對一個Project做所有的tags搜尋的話, 使用tags是比較正確的, 而./tags只能對某個檔案的目錄做搜尋.
所以一般設定的方式為先找檔案路徑, 再找目前vim的路徑.
而設定如下:
set tags=./tags,tags
參考資料 :
vim裡面的:help tags指令
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年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月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年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月10日 星期二
| [+/-] |
vim我會用的指令 |
在unix上編輯東西當然少不了vim。雖然沒有視窗的直覺化,但是透過簡潔的指令,我們更能專注於我們要編輯的內容,而不是隨意的剪剪貼貼。
下面介紹編輯檔案好用的多檔編輯:
1. 開啟檔案時可以 vim file1 file2 ... 一次開啟好多檔案。
2. 輸入 :files 會出現檔案名稱以及檔案編號。
3. :n 可以編輯下一個檔案
4. :N 可以編輯上一個檔案
5. :b# #代表輸入 :files 以後出現的檔案前面的編號,用來跳到編號為#的檔案編輯。
6. 按 Ctrl + ^ ,可以切換目前檔案以及前一個編輯的檔案。
透過這些指令在多個檔案的編輯也可以很簡單達成。
其他詳細的 vim 介紹,可以到鳥哥的 Linux 私房菜 - vi 文書處理器或是大家來學 Vim 一個歷久彌新的編輯器找到詳細內容。
參考資料 :
鳥哥的 Linux 私房菜 - vi 文書處理器 - http://linux.vbird.org/linux_basic/0310vi.php
大家來學 Vim 一個歷久彌新的編輯器 - http://edt1023.sayya.org/vim/
2008年6月9日 星期一
| [+/-] |
Unix Socket程式範例 |
Server :
建立socket -> 設定local address -> 將socket bind在local port上 -> listen client socket -> 當有socket連線時accept client socket -> recv/send
Client :
建立socket -> 設定remote(server) address -> connect遠端server -> 當connect成功之後 -> recv/send
範例請見參考資料。
參考資料 :
http://www.pcs.cnu.edu/~dgame/sockets/sockets.html
2008年6月5日 星期四
| [+/-] |
read function 設定Non-Blocking I/O的方式 |
利用 fcntl 或是 ioctl 來設定 Non-Blocking I/O,讓 read function 不會被 Block住:
#include <fcntl.h> //fcntl的header
#include <sys/ioctl.h> //ioctl的header
...
int flag;
//用fcntl設定Non-Blocking I/O
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
//用ioctl設定Non-Blocking I/O
ioctl(STDIN_FILENO, FIONBIO, &flag);
fcntl的完整用法是先用F_GETFL取得flags,在把flags和要改變的flag進行&、|,最後在用F_SETFL把flags設定回去。
int flags;
//取得flags
if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
{
//進行錯誤處理
}
//加入non-blocking I/O的flag
flags |= O_NONBLOCK;
//設定flags
if ((flags = fcntl(fd, F_SETFL, flags)) == -1)
{
//進行錯誤處理
}
參考資料 :
Advanced Programming in the Unix Environment
| [+/-] |
C程式在Unix下取得時間 |
在Unix下取得時間的方法如下:
1. time取得系統時間 (time_t)
2. 把 time_t 的時間轉換成 struct tm 格式的時間:localtime (取得在地時間),gmtime (取得格林威治時間)
3. 用印出 struct tm 的函式來把時間用想要的格式印出:asctime (預設的格式),strftime (可以自訂輸出格式)
以上就是轉換流程,如果要把 struct tm 轉回 time_t 則是用 mktime 。
#include <time.h>
...
time_t t;
struct tm *tm_t;
//取得系統時間
t = time(NULL);
//把系統時間轉成當地時間
tm_t = localtime(&t);
//印出時間
printf("%s", asctime(tm_t));
//把strcut tm轉成time_t
//t = mktime(tm_t);
參考資料 :
http://www.cs.nctu.edu.tw/~yslin/library/linuxc/function/04.html
Standard C Date & Time - http://www.cppreference.com/stddate/index.html
2008年6月4日 星期三
| [+/-] |
Bsd裡面的ls顏色設定 |
設定的流程如下 :
1. 設定TERM這個環境變數為xterm-color (在openbsd裡面為xterm-color)
2. 確認 ls 產生顏色的方法。是用 ls --color 來設定,還是用 colorls -G 。
3. 在 .profile 檔裡面 (ksh) ,設定 alias 方便使用。例如:alias ls = 'colorls -G'
4. 更改顏色的設定,在bsd裡面是用LSCOLORS這個變數的設定
DIR=Dx
SYM_LINK=Gx
SOCKET=Fx
PIPE=dx
EXE=Cx
BLOCK_SP=Dx
CHAR_SP=Dx
EXE_SUID=hb
EXE_GUID=ad
DIR_STICKY=Ex
DIR_WO_STICKY=Ex
export LSCOLORS="$DIR$SYM_LINK$SOCKET$PIPE$EXE$BLOCK_SP$CHAR_SP
$EXE_SUID$EXE_GUID$DIR_STICKY$DIR_WO_STICKY"
上面的LSCOLORS後面的內容為一行。
詳細的介紹可以參考ls 顏色設定(in Bash shell)。
參考資料 :
ls 顏色設定(in Bash shell) - http://plog.longwin.com.tw/post/1/408
2008年6月3日 星期二
| [+/-] |
讓vim可以有變色的效果 |
在.vimrc (vim的設定檔)裡面加入
syntax on這一行, 在用vim時有程式語法的地方就會變色.
如果這樣還是不行, 就去shell的設定檔裡面 (在csh, tcsh裡面是.cshrc, 在ksh和sh裡面是.profile),
在.profile裡面加入export TERM=xterm-color
在.cshrc裡面加入setenv TERM xterm-color
如此在用vim開啟檔案的時候, 就會出現彩色的變色了.
P.S. 記得設定完.profile或是.cshrc檔以後, 要重新login, 這樣設定檔才會被重新讀取.
參考資料 :
Tsung's Blog - http://plog.longwin.com.tw/post/1/369
http://www.chu.edu.tw/~chunpo/solaris/user/docs/shell.html