亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

c++實現通用參數解析類示例

2020-01-26 15:35:25
字體:
來源:轉載
供稿:網友


main.cpp

復制代碼 代碼如下:

#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

復制代碼 代碼如下:

#ifndef PARSINGARGS_H
#define PARSINGARGS_H
/* purpose @ 解析輸入的參數,需先通過AddArgType將必須參數和可允許的參數key加入到判定列表中
 *          通過Parse中的result將結果返回,其中結果的key為合法的key,vecotr為參數列表
 *          參數列表支持去掉參數前后的引號和/對引號和/的轉義
 *
 *          特殊合法字段:
 *          格式               實際存儲值
 *          //value/"            /value"
 *          "http:///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

復制代碼 代碼如下:

#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;
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久久久久久人体| 日韩美女av在线| 成人高h视频在线| 97精品免费视频| 国产偷国产偷亚洲清高网站| 欧美日韩国产丝袜另类| 久久久久久久999| 亚洲天堂av网| 日韩一二三在线视频播| 亚洲福利小视频| 欧美日韩精品在线视频| 97在线日本国产| 久久的精品视频| 久久久亚洲国产天美传媒修理工| 国产精品入口福利| 一二美女精品欧洲| 成人深夜直播免费观看| 亚洲成av人片在线观看香蕉| 中文.日本.精品| 黑人精品xxx一区一二区| 中文字幕亚洲二区| 国产日韩在线精品av| 欧美极品xxxx| 色爱av美腿丝袜综合粉嫩av| 91麻豆国产语对白在线观看| 欧美激情久久久| 亚洲另类激情图| 久久综合国产精品台湾中文娱乐网| www.色综合| 亚洲成人xxx| 日本中文字幕不卡免费| 最近2019年中文视频免费在线观看| 国产一区二区三区久久精品| 国产综合久久久久| 色综合天天综合网国产成人网| 国产日韩欧美视频在线| 亚洲视频电影图片偷拍一区| 色综合男人天堂| 欧美日韩精品在线视频| 在线视频欧美日韩精品| 国产欧美日韩91| 欧美激情视频一区二区三区不卡| 国产精品一区二区久久| 91香蕉电影院| 亚洲精品美女久久久久| 亚洲人成在线免费观看| 亚洲自拍高清视频网站| 欧美与欧洲交xxxx免费观看| 日韩欧美在线播放| 日韩精品视频免费在线观看| 精品免费在线视频| 少妇久久久久久| 色婷婷综合成人av| 欧美激情视频一区二区| 亚洲欧美另类自拍| 欧美激情小视频| 欧美香蕉大胸在线视频观看| 国语自产精品视频在线看一大j8| 成人免费在线视频网址| 91视频88av| 欧美xxxx14xxxxx性爽| 日韩av综合中文字幕| 91手机视频在线观看| 92看片淫黄大片欧美看国产片| 国产成人一区三区| 亚洲香蕉成视频在线观看| 欧美日韩国产精品一区二区不卡中文| 久久6精品影院| 久久国产天堂福利天堂| 国产美女主播一区| 亚洲精选一区二区| 日韩av网站大全| 欧美精品在线观看| 77777少妇光屁股久久一区| 亚洲高清免费观看高清完整版| 黑人狂躁日本妞一区二区三区| 91丨九色丨国产在线| 久久精品青青大伊人av| 奇门遁甲1982国语版免费观看高清| 美女精品视频一区| 亚洲精品乱码久久久久久金桔影视| 亚洲性69xxxbbb| 丝袜美腿亚洲一区二区| 国内久久久精品| 欧美电影在线观看高清| 一本色道久久综合亚洲精品小说| 日本久久中文字幕| 亚洲成色777777在线观看影院| 欧美激情videos| 久久久久久久久久亚洲| 狠狠躁夜夜躁久久躁别揉| 精品国产老师黑色丝袜高跟鞋| 欧美日韩一区免费| 欧美激情xxxx性bbbb| 精品自拍视频在线观看| 国产成人高潮免费观看精品| 国产精品久久久久免费a∨大胸| 高清一区二区三区四区五区| 国产一区二区激情| 668精品在线视频| 日韩欧美视频一区二区三区| 欧美高清视频一区二区| 51色欧美片视频在线观看| 福利精品视频在线| 综合国产在线观看| 性色av一区二区三区| 亚洲精品一二区| 国产91热爆ts人妖在线| 久久影视电视剧免费网站清宫辞电视| 亚洲精品免费网站| 青青久久av北条麻妃黑人| 97国产精品视频人人做人人爱| 日韩在线国产精品| 亚洲图片欧美午夜| 另类少妇人与禽zozz0性伦| 国产成人在线播放| 日本高清视频精品| 日韩av影视综合网| 97视频国产在线| 欧美日韩成人网| 国产亚洲欧美日韩美女| 久久香蕉国产线看观看av| 久久99青青精品免费观看| 91精品视频专区| 亚洲电影中文字幕| 久久精品国产99国产精品澳门| 日韩av免费观影| 国产精品久久久久久亚洲调教| 国产97在线播放| 亚洲精品美女视频| 久久久在线观看| 久久精品视频在线观看| 日韩精品亚洲元码| 26uuu久久噜噜噜噜| 国产亚洲精品成人av久久ww| 在线免费看av不卡| 亚洲精品免费av| 日韩国产精品视频| 精品成人69xx.xyz| 国内精品久久久久久中文字幕| 欧美影院在线播放| 欧美乱妇高清无乱码| 97国产精品免费视频| 色婷婷av一区二区三区久久| 久久精品国产精品亚洲| 国产精品第三页| 亚洲欧美日韩在线一区| 欧美极品在线视频| 欧美成人激情视频免费观看| 欧美久久精品午夜青青大伊人| 中文字幕欧美日韩va免费视频| 成人免费网站在线看| 久久伊人精品天天| 91在线精品播放| 亚洲精品在线观看www| 午夜精品久久久久久久久久久久久| 亚洲国产欧美一区二区三区久久| 国产不卡av在线| 亚洲性无码av在线| 成人激情视频免费在线| 大胆欧美人体视频| 欧美成人在线免费| 欧美日韩一二三四五区| 欧美精品一区三区|