2008年4月29日 星期二

傀儡

傀儡,上研所後第一個人生感觸。實在是自己的生活切割得不順利!記得去年暑假,因為宿舍沒申請網路,反而把生活切得很乾淨!可真是因禍得福呢!最近感到生活常常就被工作綁著!但也不是不喜歡工作或什麼的,大概是物極必反,當你成天都接觸著程式時,心中的情緒不斷累積著而無得到釋放,將倍感苦悶。

因此,我也開始嘗試不一樣的生活,首先呢,就是學學別人看看漫畫!我挑了「海賊王」。接著,看看同學個人板上常出現的動畫,我隨意看了一集的「涼宮春日的憂鬱」,說真的還有點兒不懂,哈。不過生活倒真的有輕鬆許多啦!然後,我也玩玩超任遊戲「快打炫風2加強版」,發現以前在玩的時候,特別喜歡不斷地攻擊,一定要耍個昇龍拳或是個什麼勁的才過癮,但這次我反而趨向防守型的玩法,才懂招術不一定要酷炫,簡單的強拳強腳才是最殺的殺傷力!

最後,拉回主題,其實會那樣思考,主要還是在規劃未來,總覺得目前的自己,只要一碰到工作或什麼的,一不小心就會瘋狂地投入,假使運氣好一兩週搞定,那沒什麼,倘若是動輒數把月時,生活作息可真的會大大影響。至於傀儡的感觸呢?實在是跟在天才型的領導者身後,有時會擔憂自己,自己像是個傀儡般,別人說一就是一,久了連自己的思考都消聲匿跡,那這樣又怎能超越進步呢~大概是心情悶的時容易悲觀吧!

2008年4月28日 星期一

[C] 檔案處理 - 讀取出的檔案大小錯誤?

    開檔讀資料  請務必指定 mode


        FILE *fp ,*fp2;
        char buf;
        fp = (FILE*)fopen( argv[1] , "r" );
        fp2 = (FILE*)fopen( argv[2] , "w" );


        while( !feof( fp ) ){
            fread( &buf , 1, 1 , fp );
            fwrite( &buf , 1, 1 ,fp2 );
        }
        fclose( fp );
        fclose( fp2);


    以上程式  若是讀圖檔(binary)  在 unix 下可以正常地複製一張圖出來
    但在 Windows XP with SP2 上  無論是 Dev-C++ 還是 VC 6 都會出錯


    修正的方式:


        FILE *fp ,*fp2;
        char buf;
        fp = (FILE*)fopen( argv[1] , "rb" );
        fp2 = (FILE*)fopen( argv[2] , "wb" );

        while( !feof( fp ) ){
            fread( &buf , 1, 1 , fp );
            fwrite( &buf , 1, 1 ,fp2 );
        }
        fclose( fp );
        fclose( fp2);


    結論:


        不要偷懶  :p


2008年4月23日 星期三

走路渡假

三個傻瓜,就這樣搭著縣公車到民雄,吃個餃子走回了中正。偶爾就是這簡單地瘋狂一下。我還滿喜歡這種簡單的調調,就像高中無聊時會騎著腳踏車亂逛,儘管每條路都走過,但每一次經過時的心情總是很不一樣,像在追尋著每一刻的自己。

昨天考完期中考後,心血來潮翻了翻海賊王的動漫,前陣子看動畫看到骷髏先生很酷地解決了蜘蛛猴!那時心中又燃起了對海賊王的莫名興奮,就這樣又追啊追地,後來又找了漫畫看到最新的進度,實在是太想知道動畫目前的打動結果了。簡單地渡過期中考完的一夜。

除此之外,我也寫了”興趣”。為什麼說用”寫”,因為我還是在寫程式。有點枯燥乏味,但我只想用寫程式來解悶,彷彿世界上只要專注著手上的程式流程,其他的煩惱通通可拋於腦後,但這次,是興趣而非工作,就像看漫畫時,已不會覺得是種”浪費時間”,因為,我在渡假。

希望能趕快找到興趣!

2008年4月20日 星期日

[C] File Locking @ Windows & FreeBSD

使用上儘管對第三者進行 locking ,或是避免使用 BufferI /O,不然容易出現資料不同步的現象,且跟 OS 的相依性會提高,對於要移值的程式就容易頭大啦!

開發與環境

Windows XP with SP3 + Dev-C++ v4.9.9.2 (gcc 3.4.2 )
FreeBSD 6.2-RELEASE-p1 (gcc 3.4.6)

程式碼:


#ifdef _WORK_FOR_WIN32_


#include <windows.h>
#include <io.h>


#endif


void File_LockByPtr( FILE * fd )
{
#ifndef _WORK_FOR_WIN32_
        struct flock fl;
        fl.l_type = F_WRLCK;
        fl.l_whence = SEEK_SET;
        fl.l_start = 0;
        fl.l_len = 0;
        fl.l_pid = getpid();
        if( fcntl( fileno( fd )  , F_SETLKW , &fl ) < 0 )
        {
                perror("Lock File Pointer Error @ LockFilePtr");
                exit(1);
        }
#else
        HANDLE hFile = (HANDLE)_get_osfhandle(_fileno( fd ));
        OVERLAPPED ovl;
        memset(&ovl, 0, sizeof(ovl));
        if( LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &ovl) == 0 )
        {
                perror("Lock File Pointer Error @ LockFilePtr");
                exit(1);
        }
#endif


}
void File_UnlockByPtr( FILE * fd )
{
#ifndef _WORK_FOR_WIN32_
        struct flock fl;


#ifndef SYS_OPT_LOCKING_FILE_PONITER_WITHOUT_FFLUSH
        fflush(fd);
#endif


        fl.l_type = F_UNLCK;
        fl.l_whence = SEEK_SET;
        fl.l_start = 0;
        fl.l_len = 0;
        fl.l_pid = getpid();


        if( fcntl( fileno( fd )  , F_SETLK , &fl ) < 0 )
        {
                perror("Unlock File Pointer Error @ UnlockFilePtr");
                exit(1);
        }
#else
        HANDLE hFile = (HANDLE)_get_osfhandle(_fileno( fd ));
        OVERLAPPED ovl;
        memset(&ovl, 0, sizeof(ovl));


#ifndef SYS_OPT_LOCKING_FILE_PONITER_WITHOUT_FFLUSH
        fflush( fd );
#endif


        if( UnlockFileEx(hFile, 0, 1, 0, &ovl) == 0 )
        {
                perror("Unlock File Pointer Error @ UnlockFileByPtr");
                exit(1);
        }
#endif
}
void File_LockByFD( int fd )
{
#ifndef WIN32
        struct flock fl;
        fl.l_type = F_WRLCK;
        fl.l_whence = SEEK_SET;
        fl.l_start = 0;
        fl.l_len = 0;
        fl.l_pid = getpid();
        if( fcntl( fd , F_SETLKW , &fl ) < 0 )
        {
                fprintf( stderr , "Lock File Pointer Error @ LockFilePtr\n");
                exit(1);
        }
#else
        HANDLE hFile = (HANDLE)_get_osfhandle( fd );
        OVERLAPPED ovl;
        memset(&ovl, 0, sizeof(ovl));
        if( ( lock_status = LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &ovl) ) == 0 )
        {
                fprintf( stderr , "Lock File Pointer Error @ LockFileFD\n");
                exit(1);
        }
#endif

}
void File_UnlockByFD( int fd )
{
#ifndef WIN32
        struct flock fl;

        fl.l_type = F_UNLCK;
        fl.l_whence = SEEK_SET;
        fl.l_start = 0;
        fl.l_len = 0;
        fl.l_pid = getpid();

        if( fcntl( fd , F_SETLK , &fl ) < 0 )
        {
                fprintf( stderr , "Unlock File Pointer Error @ UnlockFilePtr\n");
                exit(1);
        }
#else
        HANDLE hFile = (HANDLE)_get_osfhandle( fd );
        OVERLAPPED ovl;
        memset(&ovl, 0, sizeof(ovl));

        if( UnlockFileEx(hFile, 0, 1, 0, &ovl) == 0 )
        {
                fprintf( stderr , "Unlock File Pointer Error @ UnlockFileByFD\n");
                exit(1);
        }
#endif
}


用法:


if( ( opt->dblock = fopen( lock_file , "w" ) )  == NULL )
{
         fprintf( stderr , "Cannot Open Lock File @ DB_Lock\n" );
         exit(1);
}
File_LockByPtr( opt->dblock );

...

File_UnlockByPtr( opt->dblock );
fclose(opt->dblock);



#ifndef WIN32
        struct flock fl;
        if( ( db_lock_fd = open( db_lock_file ,  O_RDWR | O_CREAT ) )  == -1 )
#else
        HANDLE hFile;
        OVERLAPPED ovl;
        if( ( db_lock_fd = _open( db_lock_file ,  _O_RDWR | _O_CREAT , _S_IREAD| _S_IWRITE ) )  == -1 )
#endif
        {
                switch( errno )
                {
                case EACCES:
                        printf("Tried to open read-only file for writing, file's sharing mode does not allow specified operations, or given path is directory.\n");
                        break;
                case EEXIST:
                        printf("_O_CREAT and _O_EXCL flags specified, but filename already exists.\n");
                        break;
                case EINVAL:
                        printf("Invalid oflag or pmode argument.\n");
                        break;
                case EMFILE:
                        printf("No more file descriptors available (too many open files).\n");
                        break;
                case ENOENT:
                        printf("File or path not found.\n");
                        break;
                }
                fprintf( stderr , "Cannot Open Lock File @ db_lock ,%d, %s\n" , errno , db_lock_file );
                exit(1);
        }
        File_LockByFD( db_lock_fd );

        ...

        File_UnlockByFD( db_lock_fd );


2008年4月19日 星期六

工作與興趣的分隔線

今早悟出一個心得:「工作的部分,用工作的態度面對;興趣的部分,用興趣的態度面對」。

這樣的分界,是因為些前都是用興趣的方式來面對工作,所以很容易因為工作上的興趣缺缺,導致事情進行起來,苦悶許多!但這樣的分界不是對兩邊的負責態度不一,而是處理上時,心態需要微調。

昨天,原本想改寫學長寫的程式架構,覺得彈性不夠大,但說穿了只是想要用自己的方式去詮釋!今早花了點時間將其架構走了一遍,工作還是要用工作的態度面對,儘管整體架構不是自己熟悉的 framework ,就把它當做訓練跟別人合作吧!學會欣賞別人的架構,也是一門重要的學問!人,總要站在巨人的肩膀上!

至於興趣?最近花了很多時間在工作上,我想,我該為我的興趣負點責任,該花點時間想點好玩的事來碰碰。

2008年4月18日 星期五

傳承

四月天,嗅到一點離別的滋味。

相信在沒多久,自己就要負荷起實驗室中的老大哥。心情有點兒不適,或者更說是不捨。小大一常常跑來詢問東探望西的,未來若沒了現在的老大哥,總覺得自己的能力似乎還不夠稱職,然而,簡單的談天,其實也挺自在舒服的。

最近上頭的開始在進行一連串的移交,傳承,很巧地我碰上了這個交界點,或許又將學習到很多的東西,至少得提足精神好好面對,珍惜一切的機會,相信,躍進會從此開始的。

簡單的信念:「我想要成功」,儘管現在苦哈哈的,但相信與身體力行,一定會有好結果的!

2008年4月17日 星期四

空‧心

有股空虛的感觸,抹一點心虛的成份。 悶悶的,想玩卻不知要玩什麼,想睡,最近卻常常睡不好?

剛終於看了一下學長設計的介面,發現差別真大!自己的能力還差那麼多。除此之外,接近六月,又是個離別潮,耳邊常傳來”誰誰誰將要離開,未來不知該請教誰了!”,說真的,自己倒還不能獨當一面,能力這種東西,沒想到日積月累差異真大,而碩班的生活,說穿了只是幫人做事,真正想要專研自己的方向的機會,少之又少,我甚至會懷疑,科技替代役的履歷表上,將有幾項是碩班可拿出成果?時間過得真的很快,我也漸漸落於嘴砲的旋渦中。

最近太善變,心情好的時候很好,糟的時候很悶,開始能體會某人在大學時跟我說過的話,善變,有時不需要理由,也終將釐不清!彷彿剛剛證明出來的式子,一下子就被指出矛盾的地方,怎麼證都證不好,那答案,是否真的重要?我開始欣賞,那位竟然可以這麼自在地順起情緒行事,而我,放不開。

成天寫程式的生活太過單調,征服的快感也只是一瞬,我該找點樂子熱熱場子。

2008年4月15日 星期二

考試時刻

又到了期中考,這學期很忙,忙著Meeting、忙著Thinking、忙著Coding。

電腦前播放著兒時熟悉的哆啦ㄟ夢,沒想到那幼稚園的氣氛讓我倍感輕盈。洗澡時想起上學期很白癡的行為舉止,儘管二十五歲偶爾也會累犯。總是到了考試時,才會靜下來想想東西,摸摸古老的回憶。逛逛許久沒到訪的個人板,一篇篇六七年前的文章,一字字想也不敢想的青澀詞句,一股腦兒跌進眼簾,原來過去是那般,那般地叫人不敢回想,隨著時間往往已不是舊式的自己,拾不起的點滴再也沒有起點。

喜歡哆啦ㄟ夢的日語配音,也只有這份熟悉才叫醒兒時的自我。日子果然倏地變動,或許回憶是存在對現實的不安全感吧!

2008年4月11日 星期五

moai

moai,我大學認識的同學,前陣子說要寫一點關於他跟我的回憶,現在比較有空,就寫寫記錄一下。

moai,桃園人,說真的第一次見到他時,我真覺得他長得非常像我小舅舅!不曉得這樣的感觸是不是建立在親戚也是桃園人的關係。非常喜歡數學,也喜愛籃球,籃球很強,原先是得分後衛轉任控球後衛。大三還大四時,偶爾會跟他去籃球場投投球,三分球很準,沒人打擾大概投10中7。

記得,大一上我沒帶電腦,除了跟室友借電腦外,最常去打擾的就是moai了!用著P3-450的電腦,簡單的Windows2000,以及永遠播不停的 Windows Media Player。電腦對他而言,就只要聽音樂就夠了。當然,大一還有計概作業,還要寫寫程式啦,也不知道是不是自己游移的關係,我好像順道幫不少人 debug 。除此之外,他竟然最近才學會重灌電腦!想起來,就連我大五時還負責幫他重灌電腦呢!還記得大四考完台大後,馬上就是去他家重灌咧!

對 moai 最深的印象,是大一當看護的日子,因為班上同學腸胃炎掛急診,我跟 moai 就在新竹馬偕醫院幫忙看守和換班,那次恰好是輪到凌晨班次,大一通常比較猛!就這樣為了不睡著,東聊西聊的,moai還秀了一段八極拳,印象中是他高中物理老師教的,然後我則是說了漏漏長的愛情故事給他聽,現在想起來還真的有點蠢,不曉得是不是這樣的關係,除了大學室友和 moai 外,便很少會聊起自己的愛情。那時好像講了數個小時!從國中講到高中。看護的工作其實很簡單,就只是提醒護士要更換點滴,說真的我還有點不平衡?!總覺得那是護士該做的工作,哈。除此之外,深夜的急診室也令人感觸良多,就像黑洞般地將所有煩惱吸光,眼前的感受就只剩著生老病死!最後,幫忙看護也挺不錯,還得到500元的書店禮卷。

與 moai 會那麼多交集,大概是修課的關係,我們一起修微積分榮譽班、普物榮譽班,一起到圖書館打拼唸書,還有系籃的室友,所以會有聊不完的系籃話語,打不完的AOC,最扯的一次是我找他去上普物,他說等一下就去,結果我連上幾堂課後,回到寢室時他還在打AOC!微積分常常看著天才教授,喜歡模仿著她的口音,也一同被教授唸,哈,結果 moai 還修了九十幾分,我才七十多分。

記得,大一的 moai 很黏高中麻吉,幾乎每週回家,幾乎都跟好友聚聚打球等等,也幾乎沒參加過任何系上辦的活動,直到要升大二時,恰好我擔任迎新宿營的招生&攝影組長,好像是這樣藉機拉了他進來,沒多久 moai 也展示了他的表演的天份,相聲!說到相聲,他那時很瘋狂,常常會窩在我這間寢室聽相聲,聽就算了,還是聽凌晨,搞得我都睡不著!大概是從那時起,moai 開始活躍於系活動,參加了系學會、參加了暑期的應數營,也結交了上大學的第一位女朋友。

moai 的戀情滿悲苦?大一,我第一次看著一個男生,用衛生紙寫字給他欣儀的女孩,他說,這是他們高中溝通的秘密通道。接著,我看著他寫著書法,又看著他到各處景點拍著夜景!只是他不知道拍夜景的技巧,所以拍到的都是黑鴉鴉的一片,但在我的眼中,我瞧見了天真可愛的男生,用自己的雙手做出心意。只是當時的情緣未到,他和他的女孩,只能是兩個世界的人。那時的他,還是常常開著車南北跑,但女孩,最後找到合適的對象,moai因此十分傷心,我記得那時我勸說了他很久,他最後才漸漸釋懷,和營隊認識朋友,談起了小戀愛。峰迴路轉,沒想到 maoi 喜歡的那個女孩單身,這時的 moai 十分痛苦,一位是小戀愛,另一位是最深的期待,又掙扎,最後他告訴了我他的選擇,他決定放開了小戀愛,畢竟 moai 無法抹去那最初的心動,世界上也沒有完美的解法,早點結束也比最後劈腿來得好,就這樣,moai又回到過去的自己,依舊南北奔波,儘管只是好朋友的身份。有時我在想,或許是我自己誤了 moai ,讓他傷了其他人,但這就是命運吧?

慶幸的,moai 經過幾年的努力,最後終於追到女孩!!不過這也已經過兩年後!去年, moai 還擔憂地找我閒聊,很擔心對方的家長看不起他,我則告訴他就專心考研究所,畢竟讀書是他的最愛,就用他能做的表現去實現,值得高興的!他真的考上了台大!記得大一的他就說著要考轉學考!現在,他更接近了理想的舞台。

雖然我大二就轉系, moai 還是很常跑到我的寢室,還是常常會閒聊,還有打球聚餐聊天,雖然不像大一修同樣的課,跑同樣的教室,但碰面的那一刻,還是很熟悉。希望他在台大能夠追逐心中的夢想!

2008年4月10日 星期四

緩緩‧腳步

耳邊傳來熟悉的氣氛,咖啡王子1號店的音樂,好久沒悠閒一下了!今天實驗室的大學長突然跟我們說有雲門舞集免費的票可領取,不一會兒,至少拿了四對票吧!我也湊熱鬧領了兩張,到時去不成大概再送給有緣人囉

最近很繁忙,滿多事,直到春假完一兩天,才放鬆一會,但緊接著又是期中考了!心態上不一會兒又落到上學期末的心境,彷彿忙完後會為自己做的感到空虛?!我想我還沒調適好生活比例,這大概是物極必反的心態吧。

今天我跑去逛逛以前實驗室的網站,發現論壇區有大學專題教授分享研究心情,看啊看啊,不一會兒又反省了一下自己,擔心再這樣下去,自己會越來越接近瞎忙。並不是替老師做事學不到東西,只是總覺得好像是在別人的想法中過生活?這是翅膀硬了的現象嗎?不過,我倒還滿臣服於老師的,實在是老師太聰明太強大!比知識理當輸,但比實作更是輸到脫褲子!上學期曾經跟學長閒聊,覺得自己的主管一定要比我還要強,不然自己無法接受對方的領導,但我跟兩位學長聊過這些,他們一同表示,社會是一點一滴地搭建,每個人都有各自的方向與能力,搭配起來才會越變越好,如果只是持著這樣的心態,反而無法合作。這是簡單的道理,我也非常清楚,但很神奇的是自己有時很難接受,彷彿一起合作時,除了擔心自己的工作外,又怕夥伴不做事吧!

生活越變越好,偶爾也該善待一下自己囉!

2008年4月8日 星期二

[C] qsort - compare function

    好弱  摸很久還不是很懂  囧  最後 google 紀錄一下
    突然想起第一次監考時  有學弟還問我怎樣 call qsort
    大學還真的沒用過  倒是寫了幾次 qsort

    資料來源 http://mail.lssh.tp.edu.tw/~hlf/class-1/lang-c/qsort.htm

    void qsort(  void* base, size_t n, size_t size, int (*cmp)(const void*, const void*)  )

    陣列基礎的快速排序法函數,陣列是參數 base,n 是陣列大小,size 是每個
    元素的大小,最後的參數是指向函數的指標,這是比較元素大小的函數( 即上面
    compare() 函數)。

    其實最重要的是 compare 該怎樣寫, 以 sorting 一個 int array[Num] 來說

        呼叫
            qsort( (void*) array , Num , sizeof( int ) , compareInt );
        定義
            int compareInt(const void *a, const void *b)
            {
                int c = *(int *)a;
                int d = *(int *)b;
                if(c < d)           //傳回 -1 代表 a < b
                    return -1;
                else if (c == d)    //傳回   0 代表 a = b
                    return 0;
                return 1;           //傳回  1 代表 a>b
            }

    上面寫得很淺顯易懂  程式碼的重點擺在 readability

    接著就是對一個 char * array[Num] 來說
    這是我常常一時之間摸不透的東西  Orz

        呼叫
            qsort( (void*) array , Num , sizeof( char* ) , compareString );
        定義
            int compareString(const void *a, const void *b)
            {
                return strcmp(*(char **)a, *(char **)b);
            }

2008年4月1日 星期二

從 Java 到 C 的嚴重使用錯誤

    這陣子寫了一堆 C 的 func  搞了一點 point 的東東
    其中有件事讓我印象很深  特別記一下

    由於前一次開發較大型的系統是使用 Java
    我在 Java 上習慣設計一些很方便的 function  在此以數字加減運算當做例子

        String getValueByI( int x );    // 傳入整數  轉換成字串回傳
        int getValueByS( String s );    // 傳入字串  轉換成整數回傳

    如此  我可以使用

        String result = getValueByI( getValueByS( "5566" ) + 7788 );

    這樣我可以方便地做數字跟字串的轉換和運算  結果我在 C 這邊使用:

        uchar* getValueByI( int x );
        int getValueByS( uchar* s );

    使用:

        uchar * result = getValueByI( getValueByS( "5566" ) + 7788 );

    其實看上面一次好像沒什麼錯  來跑個迴圈吧

    uchar* getValueByI( int x ){
        uchar* tmp;
        tmp = malloc( sizeof(uchar) * 10 );
        sprintf( tmp , "%d" , x );
        tmp[9] = '\0';
        return tmp;
    }
    int main(){
        uchar* result, *tmp;
        while( 1 ){
            if( tmp == NULL )
                result = getValueByI( getValueByS( "5566" ) + 7788 );
            else
                result = getValueByI( getValueByS( tmp ) + 7788 );
            tmp = result;
        }
        return 0;
    }

    如此一來 tmp 之前所指的空間  會一直忘記 free 掉
    只是不斷地接另一個新的空間
    出錯的問題很簡單  那就是我在 getValueByI 裡進行 malloc 來回傳出來
    這個用法我覺得很直觀  但其實 C 並沒有 Java 的 garbage collection
    所以更正確的用法是用完必須 free 掉  特別是開發給 Server 用的
    結果我一連寫了10個 function 都是這種 style 囧rz
    這下不知要改多少啊  XD