keer_zu 发表于 2020-6-15 16:01

命令参数的解析

本帖最后由 keer_zu 于 2020-6-16 09:21 编辑

刚写了一个命令参数解析的程序,使用getopt。

主要代码如下:

#include <stdio.h>
#include <string>
#include <map>
#include <stdlib.h>

#include "operation.h"

using namespace std;
std::map<char,operation_context_t> operation_contexts;

#define no_argument 0
#define required_argument 1
#define optional_argument 2


struct option *options = NULL;

static int operation_p(char *arg)
{
    TestItemManager &tm = (TestItemManager&)TestItemManager::GetInstance();
    tm.TestItemPrint();
}

static int operation_test(char *arg)
{
    TestItemManager &tm = (TestItemManager&)TestItemManager::GetInstance();
    tm.TestSpecific(arg);
}

static int operation_a(char *arg)
{
    TestItemManager &tm = (TestItemManager&)TestItemManager::GetInstance();
    tm.TestAll();
}



void operation_contexts_init()
{
      int i = 0;
      char opt;
      opt = 'p';
      operation_contexts.insert(pair<char,operation_context_t>(opt,{.m_option={.name = "p",.has_arg=no_argument,.flag=NULL,.val=opt},.operation=operation_p}));
      opt = 't';
      operation_contexts.insert(pair<char,operation_context_t>(opt,{.m_option={.name = "test",.has_arg=required_argument,.flag=NULL,.val=opt},.operation=operation_test}));
      opt = 'n';
      operation_contexts.insert(pair<char,operation_context_t>(opt,{.m_option={.name = NULL,.has_arg= 0,.flag=NULL,.val=opt},.operation=operation_null}));

      options = (struct option *)malloc(sizeof(struct option) * operation_contexts.size());
      if(options != NULL) {
                map<char,operation_context_t>::reverse_iterator iter;
                for(iter = operation_contexts.rbegin(); iter != operation_contexts.rend(); iter++) {

                        options.name = ((operation_context_t)(iter->second)).m_option.name;
                        options.has_arg = ((operation_context_t)(iter->second)).m_option.has_arg;
                        options.flag = ((operation_context_t)(iter->second)).m_option.flag;
                        options.val = ((operation_context_t)(iter->second)).m_option.val;
                        i ++;
                }
      }
}

int run_operation(char opt,char *arg)
{
      map<char,operation_context_t>::iterator iter;

    iter = operation_contexts.find(opt);

    if(iter != operation_contexts.end()){
                return operation_contexts.operation(arg);
    }
}



使用用例:

#include <string>
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include "operation.h"


extern struct option *options;

int main(int argc, char *argv[])
{
    int opt;
    int digit_optind = 0;
    int option_index = 0;
    std::string str = "a::b:c:d";

      operation_contexts_init();
      
      if(options != NULL) {
                while((opt = getopt_long_only(argc,argv,str.c_str(),options,&option_index))!= -1) {
                run_operation(opt,optarg);
            }
      }
}

@yyy71cj @dirtwillfly



keer_zu 发表于 2020-6-16 09:20

测试项:
头文件
#ifndef __TEST_ITEM_H__
#define __TEST_ITEM_H__

#include <string>
#include <map>


///////////////////////////////////////// test item /////////////////////////////////////////
class TestItem
{
public:
        virtual int Test() = 0;
protected:
        std::string m_itemName;
};


///////////////////////////// ublox ///////////////////////////////

class TestUblox : public TestItem
{
public:
        TestUblox(std::string itemName);
        int Test();
};


///////////////////////////// emmc ///////////////////////////////

class TestEmmc : public TestItem
{
public:
        TestEmmc(std::string itemName);
        int Test();
};

///////////////////////////// can ///////////////////////////////

class TestCan : public TestItem
{
public:
        TestCan(std::string itemName);
        int Test();
};


////////////////////////////////////////// item manager ///////////////////////////////////////

class TestItemManager {
public:
        static TestItemManager& GetInstance();
        TestItemManager();

        int TestAll();
        int TestSpecific(std::string itemName);
        int TestItemPrint();
private:
        std::map<std::string,TestItem*> m_testItems;
};

#endif



.cpp文件:

#include <iostream>
#include "test_item.h"


using namespace std;

///////////////////////////////////////// TestUblox ///////////////////////////////////////////////
TestUblox::TestUblox(string itemName)
{
        m_itemName = itemName;
}

int TestUblox::Test()
{
        cout << "== ublox test" << endl;
}

///////////////////////////////////////// TestEmmc ////////////////////////////////////////////////
TestEmmc::TestEmmc(string itemName)
{
        m_itemName = itemName;
}

int TestEmmc::Test()
{
        cout << "== emmc test" << endl;
}


///////////////////////////////////////// TestCan ////////////////////////////////////////////////
TestCan::TestCan(string itemName)
{
        m_itemName = itemName;
}

int TestCan::Test()
{
        cout << "== can test" << endl;
}


////////////////////////////////////////// item manager ///////////////////////////////////////

TestItemManager::TestItemManager()
{
        string itemName;
       
        itemName = "ublox";
        m_testItems.insert(pair<string,TestItem*>(itemName,new TestUblox(itemName)));
       
        itemName = "emmc";
        m_testItems.insert(pair<string,TestItem*>(itemName,new TestEmmc(itemName)));
       
        itemName = "can";
        m_testItems.insert(pair<string,TestItem*>(itemName,new TestCan(itemName)));
       
}


TestItemManager& TestItemManager::GetInstance()
{
        static TestItemManager t_inst;
        return t_inst;
}


int TestItemManager::TestAll()
{
        map<string,TestItem*>::iterator iter;
        for(iter = m_testItems.begin(); iter != m_testItems.end(); iter++) {
                ((TestItem*)(iter->second))->Test();
        }
}

int TestItemManager::TestSpecific(string itemName)
{
        map<string,TestItem*>::iterator iter;

    iter = m_testItems.find(itemName);

    if(iter != m_testItems.end()){
                return m_testItems->Test();
    }
}

int TestItemManager::TestItemPrint()
{
        map<string,TestItem*>::iterator iter;
        for(iter = m_testItems.begin(); iter != m_testItems.end(); iter++) {
                cout << iter->first << " ";
        }

        cout << endl;
}




页: [1]
查看完整版本: 命令参数的解析