开发者

simple getopt implementation in C++

I am implementing project specific "getopt" in C++. For this I implemented a class th开发者_StackOverflowat looks like this:

 class MyGetOptions {
 private:
     typedef std::map<std::string, bool> optionsTbl; 
     optionsTbl  m_optionsTbl;
     int         m_currentArg;

     // Prohibit copy and assignment.
     MyGetOptions ( const MyGetOptions &);
     void operator= (const MyGetOptions &);

 public: 
     MyGetOptions ();
     inline bool addOption(std::string option, bool isArgReq);
     int getOpt(int argc, char *argv[], std::string& option, std::string& optArg);

     // Debug functions.
     void printOptionTbl();
 };

Now usage of above class by providers looks as below

MyGetOptions myOpts;
    myOpts.addOption("myName", true);
    myOpts.addOption("mySettings", false);

    std::string optArg;
    std::string option;

    while( (myOpts.getOpt(argc, argv, option, optArg)) != -1 )
    {
        if(option.compare("myName") == 0)
        {
            std::cout << "The myName option is set and value is " << optArg << std::endl;
            continue;
        }
        // ... additional options.

        else if(option.compare("?") == 0 )
        {
            // print help and exit.
        }
        else
        {
            // print help and exist.
        }
    }

In the present design I am returning "?" mark if getOpt finds an option character in argv that was not registered, or if it detects a missing option argument. If all command line options have been parsed, then getOpt returns -1.

I want to distinguish when ? is returned whether argv provided was not registered or missing option argument is provided, and also want to print the option name in while loop and show to user. What is best way to achieve this? Can any one please provide guidelines or inputs?


Instead of using global variables, I prefer to use return values with combination with "?" like as below

else if ((option.compare("?") == 0) && (getOptStatus == 0))
{
    // if ? and return value 0 means finds a string in argv that is not
    // registered with add options.
    continue;
}
else if ((option.compare("?") == 0) && (getOptStatus == 1))
{
    // if ? and return value 1 means finds an option string
    // with missing option argument.
    // print help and exit.
}


The standard design for getopt() has it return the option letter that it found, or ? on error. You would capture the option letter by assignment in the loop condition:

int opt;
while ((opt = myOpts.getOpt(argc, argv, option, optArg)) != -1)
{
     ...analyze the option returned...
}

The standard getopt() has a global variable optarg to point to the argument; the reference parameter in C++ is a better choice (we might quibble about std::string versus char *).

As to error detection, the standard getopt() has variables optopt and opterr to assist. The optopt contains the letter of the option that triggered the error. The opterr can be set to 0 to indicate that getopt() should not report errors; by default, it writes an error to cerr for you.

In C++, you would avoid using global variables, but you could use some extra (private) member variables to record such details, and provide accessor functions to let you find out what is going on.


Program options have been done before. Do not reinvent unless you really must. Please consider Boost.Program_options.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜