Feeds:
文章
留言

Archive for 二月 25th, 2008

C++ 寫 Console 程式常常需要解析命令列參數,可是在 STL 並沒有提供好用的類別可供使用,之前一直很想整理一個負責此功能的類別,直到今天迫不得以抽空測試 boost 提供的 program_option 類別,以解我的 C++ 長期解析命令列參數的麻煩,以下是一個簡單的範例,針對常用的無參數、int 參數和字串參數作解析,對於不支援的參數則自動忽略,範例如下:

//—————————————————————————
#include <boostprogram_options.hpp>
#include <string>
#include <iostream>
#pragma hdrstop
//—————————————————————————

#pragma argsused
int main(int argc, char* argv[]){
    using std::string;
    using std::cout;
    using std::endl;

    namespace po = boost::program_options;
    po::options_description desc("My Commnad Line");
    desc.add_options()
        ("help,h", "help message")
        ("author,a", "Author")
        ("string,s", po::value<string>(),"run as client and connect to the specified IP")
        ("int,i", po::value<int>(), "the number of concurrent connections")
    ;

    po::variables_map vm;
    try{
        po::store( po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(), vm);
        po::notify(vm);

        if (vm.count("author")) {
          cout << "Author: Chui-Wen Chiu" << endl;
          cout << "Blog: http://chuiwenchiu.spaces.live.com" << endl;
        }

        // -h or –help
        if (vm.count("help")) {
          cout << desc << endl;
          return 1;
        }

        // -s "123 456 789" or –string="123 456 789"
        if(vm.count("string")) {
          string sip = vm["string"].as<string>();
          cout << "string: " << sip << endl;
          // connect to server…
        }

        // -i 1 or –int=1
        if(vm.count("int")) {
          int t = vm["int"].as<int>();
          cout << "int: " << t << endl;
          // connect to server…
        }
    }catch(boost::program_options::invalid_command_line_syntax&){
        cout << "參數語法錯誤" << endl;
        cout << desc << endl;
    }catch(boost::bad_lexical_cast&){
        cout << "參數型別錯誤" << endl;
        cout << desc << endl;
    }catch(…){
        cout << "ERROR" << endl;
    }

    return 0;
}
//—————————————————————————

雖然 boost::program_option 有提供便利的參數型別轉換,不過,我覺得設計的並不好用,所以,我個人還是覺得全部設定為字串參數,然後自己透過 boost::lexical_cast 轉換型別(program_option 內部自動完成此步驟),可以比較容易掌握 boost::bad_lexical_cast Exception 的發生。

另外,網路上有人提到 getopt 也常被用來解析命令列參數,不過沒有時間測試,未來有需要再來看看~

Read Full Post »