欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++實(shí)現(xiàn)通用參數(shù)解析類示例

 更新時(shí)間:2014年03月03日 15:09:10   作者:  
使用命令行執(zhí)行程序的時(shí)候在程序后可跟多個(gè)參數(shù)列表,而main函數(shù)的argc和argv分別存儲(chǔ)了相關(guān)的參數(shù)個(gè)數(shù)和參數(shù)內(nèi)容,而循環(huán)輸入相關(guān)的時(shí)候就需要用戶自己來解析相關(guān)參數(shù)。以下代碼用c++的方式實(shí)現(xiàn)了相關(guān)解析的封裝,使用起來非常方便


main.cpp

復(fù)制代碼 代碼如下:

#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 << "參數(shù)錯(cuò)誤" << 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

復(fù)制代碼 代碼如下:

#ifndef PARSINGARGS_H
#define PARSINGARGS_H
/* purpose @ 解析輸入的參數(shù),需先通過AddArgType將必須參數(shù)和可允許的參數(shù)key加入到判定列表中
 *          通過Parse中的result將結(jié)果返回,其中結(jié)果的key為合法的key,vecotr為參數(shù)列表
 *          參數(shù)列表支持去掉參數(shù)前后的引號(hào)和\對(duì)引號(hào)和\的轉(zhuǎn)義
 *
 *          特殊合法字段:
 *          格式               實(shí)際存儲(chǔ)值
 *          \\value\"            \value"
 *          "\\\value\""         \value"
 *
 *          注意事項(xiàng):
 *              1、輸入?yún)?shù)列表中參數(shù)分隔以空格區(qū)分
 *              2、- 后跟單字符關(guān)鍵字,--后跟長字符串關(guān)鍵字
 *              3、關(guān)鍵字不能重復(fù)出現(xiàn),長短關(guān)鍵字不能同時(shí)出現(xiàn)在參數(shù)列表,否則會(huì)Parse函數(shù)會(huì)提示參數(shù)錯(cuò)誤
 *
 *          用法:
 *              ParsingArgs pa;
 *              pa.AddArgType('l',"getlist", ParsingArgs::NO_VALUE); //NO_VALUE關(guān)鍵字后不能有參數(shù)
 *              pa.AddArgType('p',"getuser", ParsingArgs::MAYBE_VALUE); //MAYBE_VALUE 關(guān)鍵字后可能有關(guān)鍵字
 *              pa.AddArgType('o',"outFile", ParsingArgs::MUST_VALUE); // MUST_VALUE 關(guān)鍵字后必須有參數(shù)
 *              std::map<std::string, std::vector<std::string> > result;
 *              int iRet = pa.Parse(tmpPara,result); //result以輸入關(guān)鍵字為key存儲(chǔ)相關(guān)的值序列
 *
 * 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 @ 添加解釋參數(shù),一個(gè)參數(shù)可以是長參數(shù),也可以是縮寫的段參數(shù),短參數(shù)只能為單字符,longName和shortName至少要有一個(gè)
     * para @ shortName 短參數(shù)名,0為不要短參數(shù)
     * para @ longName 長參數(shù)名 ,NULL為不要長參數(shù)
     * para @ flag 是否需要參數(shù),0不需要,1必須要,2可要可不要
     * return @ true 添加成功,false添加失敗
    */
    bool AddArgType(const char shortName, const char * longName = NULL, KeyFlag flag=NO_VALUE);

    /* pur @ 根據(jù)參數(shù)類型解釋傳入的字符串
     * para @ paras 需要解釋的字符串
     * para @ result 返回解析后的結(jié)果
     * para @ errPos 當(dāng)錯(cuò)誤的時(shí)候返回出錯(cuò)的大概位置
     * return @ 0 解釋成功,負(fù)數(shù) 解釋失敗
     *          -1 未知參數(shù)錯(cuò)誤
                -2 不能有參數(shù)的選項(xiàng)有參數(shù)錯(cuò)誤
     *          -3 必有參數(shù)選項(xiàng)后沒有跟參數(shù)
     *          -4 關(guān)鍵字沒有加入到AddArgType中
     *          -5 關(guān)鍵字重復(fù)
    */
    int Parse(const std::string & paras, std::map<std::string, std::vector<std::string> > & result, std::string &errPos);

private:
    /* pur @ 判定傳入的參數(shù)是否是已經(jīng)添加的參數(shù)類型,如果是則去掉-或--,并返回
     * para @ key 要判定的參數(shù)
     * return @ -1 不是合法參數(shù)類型 否則返回Option中的flag
    */
    KeyFlag GetKeyFlag(std::string &key);

    /* pur @ 刪除關(guān)鍵字前的-或--
    */
    void RemoveKeyFlag(std::string & paras);

    /* pur @ 從Paras中獲取一個(gè)單詞,自動(dòng)過濾掉單詞前后引號(hào),并實(shí)現(xiàn)\對(duì)空格和引號(hào)的轉(zhuǎn)義
     * para @ Paras 返回第一個(gè)單詞后的所有內(nèi)容
     * para @ word 返回第一單詞
     * return @ 成功返回true,false失敗
     */
    bool GetWord(std::string & Paras, std::string & word);

    /* pur @ 檢查關(guān)鍵字是否重復(fù)
     * para @ key 被檢查的關(guān)鍵字
     * para @  result已存儲(chǔ)的關(guān)鍵字序列
     * return @ true 是重復(fù)的,false不重復(fù)
    */
    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; //參數(shù)信息列表
};

#endif

parsingargs.cpp

復(fù)制代碼 代碼如下:

#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中獲取一個(gè)單詞,自動(dòng)過濾掉單詞前后引號(hào),并實(shí)現(xiàn)\對(duì)空格和引號(hào)的轉(zhuǎn)義
 * para @ Paras 返回第一個(gè)單詞后的所有內(nèi)容
 * para @ word 返回第一單詞
 * return @ 成功返回true,false失敗
*/
bool ParsingArgs::GetWord(std::string & Paras, std::string & word)
{
    size_t iNotSpacePos = Paras.find_first_not_of(' ',0);//查找第一個(gè)非空格字符位置
    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
                    {//最后一個(gè)是空格
                        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)
                { //找到匹配的括號(hào)
                    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; //關(guān)鍵字重復(fù)
    }

    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; //參數(shù)標(biāo)識(shí)
    std::string sKey = ""; //key關(guān)鍵字
    bool bFindValue = false; //是否已經(jīng)有value
    while(!tmpString.empty())
    {
        std::string word = "";

        bool bRet = GetWord(tmpString, word);

        if(bRet == false)
        {
            errPos = tmpString;
            return -4;//參數(shù)解析錯(cuò)誤
        }
        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;// 沒有發(fā)現(xiàn)相關(guān)的key
                            }
                        }
                        break;
                    case NO_VALUE:
                        errPos = tmpString;
                        return -2; //不能有參數(shù)的選項(xiàng)后有參數(shù)
                    default:
                        errPos = tmpString;
                        return -1;//參數(shù)錯(cuò)誤
                }//switch end
            }
        }
    }//while end
    return 0;
}

相關(guān)文章

  • C語言詳解函數(shù)與指針的使用

    C語言詳解函數(shù)與指針的使用

    C語言這門課程在計(jì)算機(jī)的基礎(chǔ)教學(xué)中一直占有比較重要的地位,然而要想突破C語言的學(xué)習(xí),對(duì)函數(shù)和指針的掌握是非常重要的,本文將具體針對(duì)函數(shù)和指針的關(guān)系做詳盡的介紹
    2022-04-04
  • Qt5升級(jí)到Qt6分步遷移教程小結(jié)

    Qt5升級(jí)到Qt6分步遷移教程小結(jié)

    Qt框架的一個(gè)新的長期支持版本6.5最近發(fā)布,本文主要介紹了Qt5升級(jí)到Qt6分步遷移教程小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • C/C++中組合詳解及其作用介紹

    C/C++中組合詳解及其作用介紹

    這篇文章主要介紹了C/C++中組合的詳解及其作用介紹,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • C++與C語言的區(qū)別你知道嗎

    C++與C語言的區(qū)別你知道嗎

    這篇文章主要為大家詳細(xì)介紹了C++與C的區(qū)別,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 利用C語言實(shí)現(xiàn)猜數(shù)字游戲

    利用C語言實(shí)現(xiàn)猜數(shù)字游戲

    這篇文章主要為大家詳細(xì)介紹了利用C語言實(shí)現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • c++中的stack和dequeue解析

    c++中的stack和dequeue解析

    這篇文章主要介紹了c++中的stack和dequeue介紹,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • 解析Linux內(nèi)核的基本的模塊管理與時(shí)間管理操作

    解析Linux內(nèi)核的基本的模塊管理與時(shí)間管理操作

    這篇文章主要介紹了Linux內(nèi)核的基本的模塊管理與時(shí)間管理操作,包括模塊加載卸載函數(shù)的使用和定時(shí)器的用法等知識(shí),需要的朋友可以參考下
    2016-02-02
  • C++編譯器和鏈接器工作原理及使用方法完全指南

    C++編譯器和鏈接器工作原理及使用方法完全指南

    本文將詳細(xì)介紹C++中的編譯器和鏈接器以及它們的工作原理及使用方法全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • vscode 安裝go第三方擴(kuò)展包填坑記錄的詳細(xì)教程

    vscode 安裝go第三方擴(kuò)展包填坑記錄的詳細(xì)教程

    這篇文章主要介紹了vscode 安裝go第三方擴(kuò)展包填坑記錄,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Opencv Hough算法實(shí)現(xiàn)圖片中直線檢測

    Opencv Hough算法實(shí)現(xiàn)圖片中直線檢測

    這篇文章主要為大家詳細(xì)介紹了Opencv Hough算法實(shí)現(xiàn)圖片中直線檢測,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12

最新評(píng)論