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月23日 星期二
| [+/-] |
[C/C++] 轉換編碼的function (iconv) |
在C/C++裡面使用iconv function包含下列三步驟:
1. 用iconv_open建立一個iconv_t的變數
2. 呼叫iconv執行轉換
3. 用iconv_close來結束iconv_t的變數
下面這一段code是把iconv包成一個function方便使用:
string pwtIconv(string buf, string fromCode, string toCode)
{
iconv_t cd;
char tmp[1000];
string outBuf;
size_t inBytesLeft, outBytesLeft;
const char *inTmp;
char *outTmp;
cd = iconv_open(toCode.c_str(), fromCode.c_str());
if(cd == ((iconv_t) - 1))
{
if(errno == EINVAL)
cout << "no conversion from " << toCode << " to " << fromCode << endl;
else
cout << "conversion setup error" << endl;
fflush(stdout);
return "";
}
//type conversion
inTmp = buf.c_str();
outTmp = tmp;
//set initial length of in and out string
inBytesLeft = buf.length() + 1;
outBytesLeft = 1000;
while(inBytesLeft > 0)
{
size_t iconv_value;
iconv_value = iconv(cd, &inTmp, &inBytesLeft, &outTmp, &outBytesLeft);
if(iconv_value == (size_t) - 1)
{
cout << "some error" << endl;
fflush(stdout);
break;
}
}
outBuf = tmp;
iconv_close(cd);
return outBuf;
}
有些錯誤檢查沒有很嚴謹,但是資料正常應該是能運作。
參考資料 :
http://www.gnu.org/software/libtool/manual/libc/iconv-Examples.html#iconv-Examples
2008年9月19日 星期五
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月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時間。
參考資料 :
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
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
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