源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

c++实现通用参数解析类示例

  • 时间:2021-09-09 02:17 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:c++实现通用参数解析类示例
main.cpp
[u]复制代码[/u] 代码如下:
#include <iostream> #include <getopt.h> #include "parsingargs.h" #include <string.h> using namespace std; int main(int argc, char * argv[]) {     //string tmpPara = "-p \"4567\" --out 1.log "; //ok     //string tmpPara = "xxxx -p \"4567\" --out 1.log ";//ok     //string tmpPara = "-p \"4567\" --out 1.log 2.log"; //ok     string tmpPara = "";     for(int i=1;i <argc; i++)     {         cout << i << "=" << argv[i] <<"---"<< endl;         if(strlen(argv[i]) == 0) //处理空字符串         {             cout << "find NULL" << endl;             tmpPara += char(31);         }         else         {             tmpPara += argv[i];         }         tmpPara += " ";     }     std::map<std::string, std::vector<std::string> > result;     ParsingArgs pa;     pa.AddArgType('l',"getlist", ParsingArgs::NO_VALUE);     pa.AddArgType('p',"getuser", ParsingArgs::MAYBE_VALUE);     pa.AddArgType('o',"outFile", ParsingArgs::MUST_VALUE);     bool bExit = false;     do     {         result.clear();         cout << "input is:" << tmpPara << "---size = " << tmpPara.size()<< endl;         std::string errPos;         int iRet = pa.Parse(tmpPara,result, errPos);         if(0>iRet)         {             cout << "参数错误" << iRet << errPos << endl;         }         else         {             map<std::string, std::vector<std::string> >::iterator it = result.begin();             for(; it != result.end(); ++it)             {                 cout << "key=" << it->first<<endl;                 for(int i=0; i<it->second.size(); ++i)                 {                     cout << "   value =" << it->second[i] << "------" << endl;                 }             }         }         string str;         cout << ">>> ";         getline(cin, tmpPara);         if(0 == tmpPara.compare("exit"))         {             bExit = true;         }     }while(!bExit);     return 0; }
parsingargs.h
[u]复制代码[/u] 代码如下:
#ifndef PARSINGARGS_H #define PARSINGARGS_H /* purpose @ 解析输入的参数,需先通过AddArgType将必须参数和可允许的参数key加入到判定列表中  *          通过Parse中的result将结果返回,其中结果的key为合法的key,vecotr为参数列表  *          参数列表支持去掉参数前后的引号和\对引号和\的转义  *  *          特殊合法字段:  *          格式               实际存储值  *          \\value\"            \value"  *          "\\\value\""         \value"  *  *          注意事项:  *              1、输入参数列表中参数分隔以空格区分  *              2、- 后跟单字符关键字,--后跟长字符串关键字  *              3、关键字不能重复出现,长短关键字不能同时出现在参数列表,否则会Parse函数会提示参数错误  *  *          用法:  *              ParsingArgs pa;  *              pa.AddArgType('l',"getlist", ParsingArgs::NO_VALUE); //NO_VALUE关键字后不能有参数  *              pa.AddArgType('p',"getuser", ParsingArgs::MAYBE_VALUE); //MAYBE_VALUE 关键字后可能有关键字  *              pa.AddArgType('o',"outFile", ParsingArgs::MUST_VALUE); // MUST_VALUE 关键字后必须有参数  *              std::map<std::string, std::vector<std::string> > result;  *              int iRet = pa.Parse(tmpPara,result); //result以输入关键字为key存储相关的值序列  *  * date    @ 2014.02.19  * author  @ haibin.wang  *  */ #include <map> #include <vector> #include <string> class ParsingArgs { public:     ParsingArgs();     ~ParsingArgs();     enum KeyFlag{ INVALID_KEY=-1, NO_VALUE, MAYBE_VALUE, MUST_VALUE};     /* pur @ 添加解释参数,一个参数可以是长参数,也可以是缩写的段参数,短参数只能为单字符,longName和shortName至少要有一个      * para @ shortName 短参数名,0为不要短参数      * para @ longName 长参数名 ,NULL为不要长参数      * para @ flag 是否需要参数,0不需要,1必须要,2可要可不要      * return @ true 添加成功,false添加失败     */     bool AddArgType(const char shortName, const char * longName = NULL, KeyFlag flag=NO_VALUE);     /* pur @ 根据参数类型解释传入的字符串      * para @ paras 需要解释的字符串      * para @ result 返回解析后的结果      * para @ errPos 当错误的时候返回出错的大概位置      * return @ 0 解释成功,负数 解释失败      *          -1 未知参数错误                 -2 不能有参数的选项有参数错误      *          -3 必有参数选项后没有跟参数      *          -4 关键字没有加入到AddArgType中      *          -5 关键字重复     */     int Parse(const std::string & paras, std::map<std::string, std::vector<std::string> > & result, std::string &errPos); private:     /* pur @ 判定传入的参数是否是已经添加的参数类型,如果是则去掉-或--,并返回      * para @ key 要判定的参数      * return @ -1 不是合法参数类型 否则返回Option中的flag     */     KeyFlag GetKeyFlag(std::string &key);     /* pur @ 删除关键字前的-或--     */     void RemoveKeyFlag(std::string & paras);     /* pur @ 从Paras中获取一个单词,自动过滤掉单词前后引号,并实现\对空格和引号的转义      * para @ Paras 返回第一个单词后的所有内容      * para @ word 返回第一单词      * return @ 成功返回true,false失败      */     bool GetWord(std::string & Paras, std::string & word);     /* pur @ 检查关键字是否重复      * para @ key 被检查的关键字      * para @  result已存储的关键字序列      * return @ true 是重复的,false不重复     */     bool IsDuplicateKey(const std::string &key, const std::map<std::string, std::vector<std::string> > & result);     struct Option     {         std::string m_longName;         char m_shortName;         KeyFlag m_flag;     };     std::vector<Option> m_args; //参数信息列表 }; #endif
parsingargs.cpp
[u]复制代码[/u] 代码如下:
#include "parsingargs.h" #include <list> ParsingArgs::ParsingArgs() { } ParsingArgs::~ParsingArgs() { } bool ParsingArgs::AddArgType(char shortName, const char * longName, KeyFlag flag) {     if(NULL == longName && 0 == shortName)     {         return false;     }     Option tmp;     tmp.m_longName = longName;     tmp.m_shortName = shortName;     tmp.m_flag = flag;     m_args.push_back(tmp);     return true; } ParsingArgs::KeyFlag ParsingArgs::GetKeyFlag(std::string &key) //返回flag, {     for(int i=0; i<m_args.size(); ++i)     {         std::string shortName = "-";         std::string longName = "--";         shortName += m_args[i].m_shortName;         longName += m_args[i].m_longName;         if( 0 == key.compare(shortName) ||                 (0==key.compare(longName))             )         {             RemoveKeyFlag(key);             return m_args[i].m_flag;         }     }     return INVALID_KEY; } void ParsingArgs::RemoveKeyFlag(std::string & word) {     if(word.size()>=2)     {         if(word[1] == '-')         {             word.erase(1,1);         }         if(word[0] == '-')         {             word.erase(0,1);         }     } } /* pur @ 从Paras中获取一个单词,自动过滤掉单词前后引号,并实现\对空格和引号的转义  * para @ Paras 返回第一个单词后的所有内容  * para @ word 返回第一单词  * return @ 成功返回true,false失败 */ bool ParsingArgs::GetWord(std::string & Paras, std::string & word) {     size_t iNotSpacePos = Paras.find_first_not_of(' ',0);//查找第一个非空格字符位置     if(iNotSpacePos == std::string::npos)     {         Paras.clear();         word.clear();         return true;     }     int length = Paras.size();     std::list<char> specialChar;     int islashPos = -1;     for(int i=iNotSpacePos; i<length; i++)     {         char cur=Paras[i];         bool bOk = false;         switch(cur)         {             case ' ':                 if(specialChar.empty())                 {                     if(i!=(length-1))                     {                         Paras = std::string(Paras, i+1, length-i-1);                     }                     else                     {//最后一个是空格                         Paras.clear();                     }                     bOk = true;                 }                 else                 {                                        if(specialChar.back() == '\\')                     {                         specialChar.pop_back();                     }                     word.append(1,cur);                 }                 break;             case '"':                 if(specialChar.empty())                 {                     specialChar.push_back(cur);                 }                 else if(specialChar.back() == cur)                 { //找到匹配的括号                     specialChar.pop_back();                 }                 else if(specialChar.back() == '\\')                 {                     word.append(1,cur);                     specialChar.pop_back();                 }                 else                 {                     word.clear();                     return false;                 }                 break;             case '\\':                 if(specialChar.empty())                 {                     specialChar.push_back(cur);                     islashPos = i;                 }                 else if(specialChar.back() == '"')                 {                     if(i<(length-1))                     {                         if('"'==Paras[i+1] || '\\'==Paras[i+1])                         {                             specialChar.push_back(cur);                         }                         else                         {                             word.append(1,cur);                         }                     }                     else                     {                         word.clear();                         return false;                     }                 }                 else if('\\' == specialChar.back())                 {                      word.append(1,cur);                      specialChar.pop_back();                 }                 else                 {                     word.clear();                     return false;                 }                 break;             default:                 word.append(1,Paras[i]);                 if(i==(length-1))                 {                     bOk = true;                     Paras.clear();                 }                 break;         }         if(bOk)         {             return true;         }     }//for end     if(specialChar.empty())     {         Paras.clear();         return true;     }     else     {         return false;     } } bool ParsingArgs::IsDuplicateKey(const std::string &key, const std::map<std::string, std::vector<std::string> > & result) {     if(result.find(key) != result.end())     {         return true; //关键字重复     }     for(int i=0; i<m_args.size(); ++i)     {         if( (key.compare(m_args[i].m_longName) == 0 && result.find(std::string(1, m_args[i].m_shortName)) != result.end())                 || (key.compare(std::string(1, m_args[i].m_shortName)) == 0 && result.find(m_args[i].m_longName) != result.end())           )         {             return true;         }     }     return false; } int ParsingArgs::Parse(const std::string & Paras, std::map<std::string, std::vector<std::string> > & result, std::string &errPos) {     std::string tmpString = Paras;     KeyFlag keyFlag = INVALID_KEY; //参数标识     std::string sKey = ""; //key关键字     bool bFindValue = false; //是否已经有value     while(!tmpString.empty())     {         std::string word = "";         bool bRet = GetWord(tmpString, word);         if(bRet == false)         {             errPos = tmpString;             return -4;//参数解析错误         }         else         {             KeyFlag tmpFlag = GetKeyFlag(word);             if(IsDuplicateKey(word, result))             {                 errPos = tmpString;                 return -5;             }             if(tmpFlag != INVALID_KEY)             {                 if(tmpFlag == MUST_VALUE && keyFlag == MUST_VALUE && !bFindValue)                 {                     errPos = tmpString;                     return -3;                 }                 keyFlag = tmpFlag;                 std::vector<std::string> tmp;                 result[word] = tmp;                 sKey = word;                 bFindValue = false;             }             else             {                 switch(keyFlag)                 {                     case MAYBE_VALUE:                     case MUST_VALUE:                         {                             std::map<std::string, std::vector<std::string> >::iterator it = result.find(sKey);                             if(it != result.end())                             {                                 it->second.push_back(word);                                 bFindValue = true;                             }                             else                             {                                 errPos = tmpString;                                 return -1;// 没有发现相关的key                             }                         }                         break;                     case NO_VALUE:                         errPos = tmpString;                         return -2; //不能有参数的选项后有参数                     default:                         errPos = tmpString;                         return -1;//参数错误                 }//switch end             }         }     }//while end     return 0; }
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部