c++中简单的getopt实现

simple getopt implementation in C++

本文关键字:getopt 实现 简单 c++      更新时间:2023-10-16

我正在用c++实现项目特定的"getopt"。为此,我实现了一个类,看起来像这样:

 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();
 };

现在提供商对上面类的使用如下所示

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.
        }
    }

在目前的设计中,如果getOpt发现argv中没有注册的选项字符,或者如果它检测到缺失的选项参数,我将返回"?"标记。如果已经解析了所有的命令行选项,那么getOpt返回-1。

我想区分当?返回时是否提供argv未注册或缺少选项参数,并且还想在while循环中打印选项名称并显示给用户。实现这一目标的最佳方式是什么?谁能提供指导或意见?

不使用全局变量,我更喜欢使用带"?"的返回值,如下所示

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.
}

getopt()的标准设计让它返回它找到的选项字母,或者在错误时返回?。您将在循环条件中通过赋值捕获选项字母:

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

标准getopt()有一个全局变量optarg指向实参;c++中的reference形参是一个更好的选择(我们可能会纠结于std::stringchar *)。

在错误检测方面,标准getopt()有变量optoptopterr来辅助。optopt包含触发错误的选项的字母。opterr可以设置为0,表示getopt()不报告错误;默认情况下,它会为你写一个错误到cerr

在c++中,您将避免使用全局变量,但是您可以使用一些额外的(私有)成员变量来记录这些细节,并提供访问器函数来让您了解发生了什么。

程序选项以前做过。除非你真的有必要,否则不要重新发明。请考虑Boost.Program_options