2007年6月14日 星期四

Boost program_options

http://www.boost.org/doc/html/program_options.html

Parse command line裡的parameters從來都不是一件簡單的事, 雖然僅僅是字串的解析, 但是沒有一個programmer還想分心去煩惱這些無關緊要的小事, 就像C++的std::string一樣, 簡單有用的設計讓programmer的生活可以輕鬆一點。

使用Java的人應該都對CLI不陌生, 它隸屬於Apache Jakarta Project下的jakarta commons。基本上Boost Program_options做的事情就跟CLI一樣, 所以使用C++的人同樣有方便好用的library可以利用。Java好像比較容易在網路上找到資源, 不管是文件或是程式庫, 都比C++多樣化, 但是Boost出現後慢慢改善了C++的這種情況, 也的確讓很多C++ developer可以更輕鬆的寫程式......離題了

Example:

namespace po = boost::program_options;
po::options_description desc("Available options");

options_description有overload << 這個operator可以output到std::ostream, 也就是說, 我們可以用cout就能印出那一長串的usage information, 格式排版完全不用擔心, 非常方便。
desc.add_options()
("help,h", "help message")
("server,s", "run as server")
("client,c", po::value<string>(),"run as client and connect to the specified IP")
("bind,b", po::value<string>(), "bind a source IP to the client")
("threads,t", po::value<int>(), "the number of concurrent connections")
;

加入選項, 第一個parameter是參數名稱, 用逗號來區分長選項和短選項, 像第一個就是可以接收--help或-h這種選項。當然也可以在選項裡設定要接受使用者輸入參數, 例如上面的--threads或-t可以讓使用者指定thread的個數。

po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);

再來就是parse command line的字串啦, argc跟argv就是那些熟悉的東西, 全部丟進去就好了, 3行code就搞定!!

if (vm.count("help"))
{
cout << desc << endl;
return 1;
}

variables_map的count方法可以得知有哪些選項出現, 如果使用者想要看help, 那就用cout直接把options_description印出來就好了。


if(vm.count("client"))
{
string sip = vm["client"].as<string>();
// connect to server...
}


直接取得剛剛已經宣告好型態的參數, 連atoi或是sprintf這些煩人的雜事都省了......

基本用法大概就是這樣, 真的非常簡單, 以後寫command line程式不用再經歷parsing parameter的痛苦了......

點滑鼠大賽......

http://www.clickclickclick.com/

怎麼會有人這麼北七呢, 這種比賽到底有什麼意義啊XD
我想唯一的意義可能是, 可以看出哪一個國家的人最閒......或是哪一個國家的人用的滑鼠最耐操。台灣現在遠遠落後啊, 愛台灣的台灣人趕快衝啊!!

初步看了一下, 開始比賽前要先輸入圖形文字, 圖形文字是彩色而且是扭曲的, 這樣比較難作弊了。按了大約20下以後, 就會出現加入國家click總和的link, 按下去就可以幫台灣加分數。很奇怪的是, 要加入總和前並不用通過圖形文字的檢查, 這裡的防弊措施僅僅是一個隨機(我猜)的連結而已, 對於精通web robot的人而言, 這應該不是什麼問題才對。因此, 可能可以做出一個robot, 一開始只要輸入圖形文字, 然後就自動按個幾千下加分, 然後再循環, 繼續輸入圖形文字這樣。不過我們不是韓國人, 不可以作弊喔, 科科。

2007年6月12日 星期二

Unicode到底是什麼?

The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

上面是一篇Joel的文章, 用淺顯易懂的文字說明Unicode的原理。不知道UTF-7, UTF-8, UTF-16, UTF-32嗎?看一下這篇文章吧......還有, wchar_t這個type在UNIX/LINUX上的GCC是4個byte, 在Windows是佔2個byte, programmer一定要注意到這個。
一般來說, unicode的implementation依平台不同, 甚至依compiler而不同, 如果想要避免這種implementation的差異, 可以用現在最portable的unicode支援 - ICU。ICU支援C/C++和Java, .NET好像沒有, 不過.NET有一個System.Text.Encoding, 這個也能支援unicode不同格式之間的互轉。

2007年6月11日 星期一

最近的超級星光大道......

最近楊蹤萎還真紅耶, 把"背叛"唱的比曹格還紅, 曹格不知作何感想......俺是不看這種節目的(碼的唱一首歌就要哭一次, 我會看到想揍人......), 但是在"耳濡目染"之下, 我對那個節目還蠻了解的......囧rz。其實背叛也不錯聽啦, 楊蹤萎唱得也很好, 我也列入我的KTV重點練習曲之一, 科科, 我還想給它改一下歌詞, 唱出來可以更符合我心裡的感慨︰


雨,不停落下來~
bug,怎麼還是在~
儘管我細心design,你要亂掰就亂掰,我一個人,欣賞悲哀~
code,只剩下無奈~
我,一直不願再去改~
程式裡指標之間,永遠都有bug能踩~
只要一改,跑不起來~~

#
緊緊相依的code如何拆分開,你比我清楚還要我說明白~
bug太多會讓人瘋狂的勇敢,我用背叛自己,完成你的喇賽~~~
把code亂改不問一句該不該,當作每週一次對你的交差
破破爛爛慘慘,今後都不管~~

*
只要你能愉快~~~

心,有一句感慨~
我,還能夠跟誰對白~~
在你要豪洨之前,請你再回頭看看~
那些虎爛,還在不在~~~

Repeat #, *
(間奏)
Repeat #, *, *

2007年6月8日 星期五

Visual C++ compile error C2011

因為用到ntohs, ntohl這些function, 所以有include到<winsock2.h>, compile時卻一直出現

'fdset' : 'struct' 型別重複定義
'hostent' : 'struct' 型別重複定義
......


很多類似這種重複定義的問題。有經驗的windows programmer應該會想到, 可能哪邊搞錯同時把<winsock.h>和<winsock2.h> include進來了, 可是search了一下project, 根本就沒有include到什麼<winsock.h>啊, 而且<winsock2.h>的開頭寫著:

#ifndef _WINSOCK2API_
#define _WINSOCK2API_
#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */


有以上的#define, 應該就不會再去include到<winsock.h>裡面的東西了吧!? 應該是這樣沒錯, 除非......你寫成這樣:

#include <winsock.h>
#include <winsock2.h>


<winsock.h>可沒有什麼預防措施以避免include到<winsock2.h>, 所以這樣的排列就會造成<winsock2.h>裡面的定義全部跟<winsock.h>裡面的衝突。但是, 前面說過了, 我沒有include <winsock.h>啊!! 謎底揭曉了, VC的<windows.h>居然include <winsock.h>......, 而且如果include關係像以下這樣, 那一時之間也很難知道發生什麼問題......

myinc.h的內容

#include <windows.h>
...


main.cpp的內容

#include "myinc.h"
#include <winsock2.h>


main.cpp並沒有include <windows.h>, 是它的include file去include到的, 如果include file很多, 找起來會想撞牆......因此, 最好的方法還是以後都把<winsock2.h>擺最上面好了。

2007年6月7日 星期四

Boost shared_ptr

shared_ptr包含於Boost Smart Pointers裡面, 它可以儲存指標, 並保證在所有存取這個指標的shared_ptr被釋放後, 這個指標所指的記憶體會自動被釋放, 這有很多實用的用途, 例如

class MyClass {...};

MyClass* getMyClass()
{
return new MyClass();
}

void foo()
{
MyClass *c = getMyClass();
c->foo_1();
// ...

// 做了一堆鳥事
// ...
c->foo_n();
// 最後忘記把c這個pointer delete掉, 造成memory leak, 掯!!
}


當然, return一個heap-allocated object是programmer所應該極力避免的, 因為這是造成memory leak的最危險因素, 但是有時候呢, 還是會碰到需要的情況啊, 例如前人寫的程式已經根深蒂固, 根本沒有辦法修改了, 但是又想避免這種memory leak的可能, 這時候shared_ptr就派上用場了!!

class MyClass {...};
shared_ptr<MyClass> getMyClass()

{
return shared_ptr<MyClass>(new MyClass());
}
void foo()
{
shared_ptr<MyClass> c = getMyClass();
// ...

// ...
c->foo_1();
// 做了一堆鳥事
c->foo_n();
// ...
// ...

// 還是忘記c這個變數的存在...囧
}



雖然到了最後, 我們還是忘記了c的存在, 但是c已經是個shared_ptr而且是local variable, 所以在foo()的最後, c這個變數會從stack裡消失, 而它所包含的指標所指向的記憶體, 也隨著它的消失而自動的被釋放了, 這世界又變的更簡單一點了。而且, 只需要更改到綠色字體部份的code, 其他code完全不受影響, 因為shared_ptr也overload了->這個operator, 所以操作起來就跟操作原來的指標一樣!!

shared_ptr之所以叫shared_ptr, 也是因為可以有多個shared_ptr包含同一個指標囉, 當然, thread-safe它也有gurantee, 在此就不舉例說明了......

2007年6月4日 星期一

Boost C++ Library

Boost當初是由C++委員會核心成員所發起的, 到現在已經是非常成熟穩定的程式庫了!!其中已經有10個library被列入C++ Standard TR1裡面, 陸續還有其他library要進入TR2!!


我的感想啊, Boost真的是C++ programmer一直以來夢寐以求的程式庫
小至能夠取代atoi這些小工具的lexical_cast
大至一整個跨平台的filesystem library
(C或C++在不同平台上的檔案處理真的是會讓人想撞牆XD, 有了Boost Filesystem從此就海闊天空了XDD)
都可以在Boost裡面找到
當然還有一些找不到啦, 例如XML和Logging這兩個常用的東西
有志者可以自己寫一套library去加入Boost喔, 不過要經過層層關卡的review, 沒有毅力恆心者請勿嘗試......