• 命令行解析器


    本文由 @lonelyrains 出品,转载请注明出处。

     
    文章链接: http://blog.csdn.net/lonelyrains/article/details/46426645


    opencv2.4.8  core.hpp 

    /*!
    "
    The CommandLineParser class is designed for command line arguments parsing
    "
               "Keys map: 
    "
               "Before you start to work with CommandLineParser you have to create a map for keys.
    "
               "    It will look like this
    "
               "    const char* keys =
    "
               "    {
    "
               "        {    s|  string|  123asd |string parameter}
    "
               "        {    d|  digit |  100    |digit parameter }
    "
               "        {    c|noCamera|false    |without camera  }
    "
               "        {    1|        |some text|help            }
    "
               "        {    2|        |333      |another help    }
    "
               "    };
    "
               "Usage syntax: 
    "
               "    "{" - start of parameter string.
    "
               "    "}" - end of parameter string
    "
               "    "|" - separator between short name, full name, default value and help
    "
               "Supported syntax: 
    "
               "    --key1=arg1  <If a key with '--' must has an argument
    "
               "                  you have to assign it through '=' sign.> 
    "
               "<If the key with '--' doesn't have any argument, it means that it is a bool key>
    "
               "    -key2=arg2   <If a key with '-' must has an argument 
    "
               "                  you have to assign it through '=' sign.> 
    "
               "If the key with '-' doesn't have any argument, it means that it is a bool key
    "
               "    key3                 <This key can't has any parameter> 
    "
               "Usage: 
    "
               "      Imagine that the input parameters are next:
    "
               "                -s=string_value --digit=250 --noCamera lena.jpg 10000
    "
               "    CommandLineParser parser(argc, argv, keys) - create a parser object
    "
               "    parser.get<string>("s" or "string") will return you first parameter value
    "
               "    parser.get<string>("s", false or "string", false) will return you first parameter value
    "
               "                                                                without spaces in end and begin
    "
               "    parser.get<int>("d" or "digit") will return you second parameter value.
    "
               "                    It also works with 'unsigned int', 'double', and 'float' types>
    "
               "    parser.get<bool>("c" or "noCamera") will return you true .
    "
               "                                If you enter this key in commandline>
    "
               "                                It return you false otherwise.
    "
               "    parser.get<string>("1") will return you the first argument without parameter (lena.jpg) 
    "
               "    parser.get<int>("2") will return you the second argument without parameter (10000)
    "
               "                          It also works with 'unsigned int', 'double', and 'float' types 
    "
    */
    class CV_EXPORTS CommandLineParser
    {
        public:
    
        //! the default constructor
          CommandLineParser(int argc, const char* const argv[], const char* key_map);
    
        //! get parameter, you can choose: delete spaces in end and begin or not
        template<typename _Tp>
        _Tp get(const std::string& name, bool space_delete=true)
        {
            if (!has(name))
            {
                return _Tp();
            }
            std::string str = getString(name);
            return analyzeValue<_Tp>(str, space_delete);
        }
    
        //! print short name, full name, current value and help for all params
        void printParams();
    
        protected:
        std::map<std::string, std::vector<std::string> > data;
        std::string getString(const std::string& name);
    
        bool has(const std::string& keys);
    
        template<typename _Tp>
        _Tp analyzeValue(const std::string& str, bool space_delete=false);
    
        template<typename _Tp>
        static _Tp getData(const std::string& str)
        {
            _Tp res = _Tp();
            std::stringstream s1(str);
            s1 >> res;
            return res;
        }
    
        template<typename _Tp>
         _Tp fromStringNumber(const std::string& str);//the default conversion function for numbers
    
        };
    
    template<> CV_EXPORTS
    bool CommandLineParser::get<bool>(const std::string& name, bool space_delete);
    
    template<> CV_EXPORTS
    std::string CommandLineParser::analyzeValue<std::string>(const std::string& str, bool space_delete);
    
    template<> CV_EXPORTS
    int CommandLineParser::analyzeValue<int>(const std::string& str, bool space_delete);
    
    template<> CV_EXPORTS
    unsigned int CommandLineParser::analyzeValue<unsigned int>(const std::string& str, bool space_delete);
    
    template<> CV_EXPORTS
    uint64 CommandLineParser::analyzeValue<uint64>(const std::string& str, bool space_delete);
    
    template<> CV_EXPORTS
    float CommandLineParser::analyzeValue<float>(const std::string& str, bool space_delete);
    
    template<> CV_EXPORTS
    double CommandLineParser::analyzeValue<double>(const std::string& str, bool space_delete);
    

    cmdparser.cpp

    #include "precomp.hpp"
    
    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    using namespace cv;
    
    namespace {
    void helpParser()
    {
        printf("
    The CommandLineParser class is designed for command line arguments parsing
    "
               "Keys map: 
    "
               "Before you start to work with CommandLineParser you have to create a map for keys.
    "
               "    It will look like this
    "
               "    const char* keys =
    "
               "    {
    "
               "        {    s|  string|  123asd |string parameter}
    "
               "        {    d|  digit |  100    |digit parameter }
    "
               "        {    c|noCamera|false    |without camera  }
    "
               "        {    1|        |some text|help            }
    "
               "        {    2|        |333      |another help    }
    "
               "    };
    "
               "Usage syntax: 
    "
               "    "{" - start of parameter string.
    "
               "    "}" - end of parameter string
    "
               "    "|" - separator between short name, full name, default value and help
    "
               "Supported syntax: 
    "
               "    --key1=arg1  <If a key with '--' must has an argument
    "
               "                  you have to assign it through '=' sign.> 
    "
               "<If the key with '--' doesn't have any argument, it means that it is a bool key>
    "
               "    -key2=arg2   <If a key with '-' must has an argument 
    "
               "                  you have to assign it through '=' sign.> 
    "
               "If the key with '-' doesn't have any argument, it means that it is a bool key
    "
               "    key3                 <This key can't has any parameter> 
    "
               "Usage: 
    "
               "      Imagine that the input parameters are next:
    "
               "                -s=string_value --digit=250 --noCamera lena.jpg 10000
    "
               "    CommandLineParser parser(argc, argv, keys) - create a parser object
    "
               "    parser.get<string>("s" or "string") will return you first parameter value
    "
               "    parser.get<string>("s", false or "string", false) will return you first parameter value
    "
               "                                                                without spaces in end and begin
    "
               "    parser.get<int>("d" or "digit") will return you second parameter value.
    "
               "                    It also works with 'unsigned int', 'double', and 'float' types>
    "
               "    parser.get<bool>("c" or "noCamera") will return you true .
    "
               "                                If you enter this key in commandline>
    "
               "                                It return you false otherwise.
    "
               "    parser.get<string>("1") will return you the first argument without parameter (lena.jpg) 
    "
               "    parser.get<int>("2") will return you the second argument without parameter (10000)
    "
               "                          It also works with 'unsigned int', 'double', and 'float' types 
    "
               );
    }
    
    vector<string> split_string(const string& str, const string& delimiters)
    {
        vector<string> res;
    
        string split_str = str;
        size_t pos_delim = split_str.find(delimiters);
    
        while ( pos_delim != string::npos)
        {
            if (pos_delim == 0)
            {
                res.push_back("");
                split_str.erase(0, 1);
            }
            else
            {
                res.push_back(split_str.substr(0, pos_delim));
                split_str.erase(0, pos_delim + 1);
            }
    
            pos_delim = split_str.find(delimiters);
        }
    
        res.push_back(split_str);
    
        return res;
    }
    
    string del_space(string name)
    {
        while ((name.find_first_of(' ') == 0)  && (name.length() > 0))
            name.erase(0, 1);
    
        while ((name.find_last_of(' ') == (name.length() - 1)) && (name.length() > 0))
            name.erase(name.end() - 1, name.end());
    
        return name;
    }
    
    }//namespace
    
    static bool keyIsNumber(const std::string & option, size_t start)
    {
        bool isNumber = true;
        size_t end = option.find_first_of('=', start);
        end = option.npos == end ?

    option.length() : end; for ( ; start < end; ++start) if (!isdigit(option[start])) { isNumber = false; break; } return isNumber; } CommandLineParser::CommandLineParser(int argc, const char* const argv[], const char* keys) { std::string keys_buffer; std::string values_buffer; std::string buffer; std::string curName; std::vector<string> keysVector; std::vector<string> paramVector; std::map<std::string, std::vector<std::string> >::iterator it; size_t flagPosition; int currentIndex = 1; //bool isFound = false; bool withNoKey = false; bool hasValueThroughEq = false; keys_buffer = keys; while (!keys_buffer.empty()) { flagPosition = keys_buffer.find_first_of('}'); flagPosition++; buffer = keys_buffer.substr(0, flagPosition); keys_buffer.erase(0, flagPosition); flagPosition = buffer.find('{'); if (flagPosition != buffer.npos) buffer.erase(flagPosition, (flagPosition + 1)); flagPosition = buffer.find('}'); if (flagPosition != buffer.npos) buffer.erase(flagPosition); paramVector = split_string(buffer, "|"); while (paramVector.size() < 4) paramVector.push_back(""); buffer = paramVector[0]; buffer += '|' + paramVector[1]; //if (buffer == "") CV_ERROR(CV_StsBadArg, "In CommandLineParser need set short and full name"); paramVector.erase(paramVector.begin(), paramVector.begin() + 2); data[buffer] = paramVector; } buffer.clear(); keys_buffer.clear(); paramVector.clear(); for (int i = 1; i < argc; i++) { if (!argv[i]) break; curName = argv[i]; size_t nondash = curName.find_first_not_of("-"); if (nondash == 0 || nondash == curName.npos || keyIsNumber(curName, nondash)) withNoKey = true; else curName.erase(0, nondash); if (curName.find('=') != curName.npos) { hasValueThroughEq = true; buffer = curName; curName.erase(curName.find('=')); buffer.erase(0, (buffer.find('=') + 1)); } values_buffer = del_space(values_buffer); for(it = data.begin(); it != data.end(); it++) { keys_buffer = it->first; keysVector = split_string(keys_buffer, "|"); for (size_t j = 0; j < keysVector.size(); j++) keysVector[j] = del_space(keysVector[j]); values_buffer = it->second[0]; if (((curName == keysVector[0]) || (curName == keysVector[1])) && hasValueThroughEq) { it->second[0] = buffer; //isFound = true; break; } if (!hasValueThroughEq && ((curName == keysVector[0]) || (curName == keysVector[1])) && ( values_buffer.find("false") != values_buffer.npos || values_buffer == "" )) { it->second[0] = "true"; //isFound = true; break; } if (!hasValueThroughEq && (values_buffer.find("false") == values_buffer.npos) && ((curName == keysVector[0]) || (curName == keysVector[1]))) { it->second[0] = argv[++i]; //isFound = true; break; } if (withNoKey) { std::string noKeyStr = it->first; if(atoi(noKeyStr.c_str()) == currentIndex) { it->second[0] = curName; currentIndex++; //isFound = true; break; } } } withNoKey = false; hasValueThroughEq = false; //isFound = false; } } bool CommandLineParser::has(const std::string& keys) { std::map<std::string, std::vector<std::string> >::iterator it; std::vector<string> keysVector; for(it = data.begin(); it != data.end(); it++) { keysVector = split_string(it->first, "|"); for (size_t i = 0; i < keysVector.size(); i++) keysVector[i] = del_space(keysVector[i]); if (keysVector.size() == 1) keysVector.push_back(""); if ((del_space(keys).compare(keysVector[0]) == 0) || (del_space(keys).compare(keysVector[1]) == 0)) return true; } return false; } std::string CommandLineParser::getString(const std::string& keys) { std::map<std::string, std::vector<std::string> >::iterator it; std::vector<string> valueVector; for(it = data.begin(); it != data.end(); it++) { valueVector = split_string(it->first, "|"); for (size_t i = 0; i < valueVector.size(); i++) valueVector[i] = del_space(valueVector[i]); if (valueVector.size() == 1) valueVector.push_back(""); if ((del_space(keys).compare(valueVector[0]) == 0) || (del_space(keys).compare(valueVector[1]) == 0)) return it->second[0]; } return string(); } template<typename _Tp> _Tp CommandLineParser::fromStringNumber(const std::string& str)//the default conversion function for numbers { return getData<_Tp>(str); } void CommandLineParser::printParams() { int col_p = 30; int col_d = 50; std::map<std::string, std::vector<std::string> >::iterator it; std::vector<string> keysVector; std::string buf; for(it = data.begin(); it != data.end(); it++) { keysVector = split_string(it->first, "|"); for (size_t i = 0; i < keysVector.size(); i++) keysVector[i] = del_space(keysVector[i]); cout << " "; buf = ""; if (keysVector[0] != "") { buf = "-" + keysVector[0]; if (keysVector[1] != "") buf += ", --" + keysVector[1]; } else if (keysVector[1] != "") buf += "--" + keysVector[1]; if (del_space(it->second[0]) != "") buf += "=[" + del_space(it->second[0]) + "]"; cout << setw(col_p-2) << left << buf; if ((int)buf.length() > col_p-2) { cout << endl << " "; cout << setw(col_p-2) << left << " "; } buf = ""; if (del_space(it->second[1]) != "") buf += del_space(it->second[1]); for(;;) { bool tr = ((int)buf.length() > col_d-2) ?

    true: false; std::string::size_type pos = 0; if (tr) { pos = buf.find_first_of(' '); for(;;) { if (buf.find_first_of(' ', pos + 1 ) < (std::string::size_type)(col_d-2) && buf.find_first_of(' ', pos + 1 ) != std::string::npos) pos = buf.find_first_of(' ', pos + 1); else break; } pos++; cout << setw(col_d-2) << left << buf.substr(0, pos) << endl; } else { cout << setw(col_d-2) << left << buf<< endl; break; } buf.erase(0, pos); cout << " "; cout << setw(col_p-2) << left << " "; } } } template<> bool CommandLineParser::get<bool>(const std::string& name, bool space_delete) { std::string str_buf = getString(name); if (space_delete && str_buf != "") { str_buf = del_space(str_buf); } if (str_buf == "true") return true; return false; } template<> std::string CommandLineParser::analyzeValue<std::string>(const std::string& str, bool space_delete) { if (space_delete) { return del_space(str); } return str; } template<> int CommandLineParser::analyzeValue<int>(const std::string& str, bool /*space_delete*/) { return fromStringNumber<int>(str); } template<> unsigned int CommandLineParser::analyzeValue<unsigned int>(const std::string& str, bool /*space_delete*/) { return fromStringNumber<unsigned int>(str); } template<> uint64 CommandLineParser::analyzeValue<uint64>(const std::string& str, bool /*space_delete*/) { return fromStringNumber<uint64>(str); } template<> float CommandLineParser::analyzeValue<float>(const std::string& str, bool /*space_delete*/) { return fromStringNumber<float>(str); } template<> double CommandLineParser::analyzeValue<double>(const std::string& str, bool /*space_delete*/) { return fromStringNumber<double>(str); }


    好多东西真的不用自己写.    联想非常重要.

  • 相关阅读:
    python3 提示No module named _sqlite3
    python3 无法使用flask.ext.* 报错的解决方法
    Java中操作时间比较好用的类
    Integer和Integer数据的大小比较
    Django学习(七) 创建第一个Django项目
    Python学习(七) 流程控制if语句
    Django学习(六) 模板
    Python学习(六) Python数据类型:字典(重要)
    Python学习(五) Python数据类型:列表(重要)
    Python学习(四) Python数据类型:序列(重要)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5174490.html
Copyright © 2020-2023  润新知