解析 C 中具有默认值和范围约束的命令选项

发布于 2024-10-09 05:35:00 字数 692 浏览 0 评论 0原文

我需要解析 C 中的命令行参数。我的参数基本上是 具有默认值和范围限制的 int 或 float。

我已经开始实现类似这样的东西:

option_float(float* out, int argc, char* argv, char* name, description,
    float default_val, int is_optional, float min_value, float max_value)

我称之为例如:

float* pct;
option_float(pct, argc, argv, "pct", "My super percentage option", 50, 1,
    FALSE, 0, 100)

但是我不想重新发明轮子!

我的目标是对范围约束进行错误检查,当 该选项不是可选的并且未设置。并通常生成帮助消息 由usage()函数给出。

使用文本看起来像这样:

--pct     My super percentage option (default : 50). Should be in [0, 100]

我已经开始使用 getopt 但它对于我想做的事情来说太有限了,我觉得它仍然 需要我为这样的简单用例编写太多代码。

您会推荐哪些替代方案?

I need to parse command line arguments in C. My arguments are basically
int or float with default values and range constrains.

I've started to implement something that look like this:

option_float(float* out, int argc, char* argv, char* name, description,
    float default_val, int is_optional, float min_value, float max_value)

which I call for example with:

float* pct;
option_float(pct, argc, argv, "pct", "My super percentage option", 50, 1,
    FALSE, 0, 100)

However I don't want to reinvent the wheel!

My objective is to have error checking of range constraints, throw an error when
the option is not optional and is not set. And generate the help message usually
given by usage() function.

The usage text would look like this:

--pct     My super percentage option (default : 50). Should be in [0, 100]

I've started with getopt but it is too limited for what I want to do and I feel it still
requires me to write too much code for a simple use case like this.

What alternatives would you recommend?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

渡你暖光 2024-10-16 05:35:00

假设您正在为 Linux 编码...

尝试 getopt_long (man 3 getopt_long) 作为双破折号选项。

另外,尝试使验证器成为通用函数,并让 getopt/getopt_long 来解析和检查选项所需参数的困难部分。

无论如何,如果您想按定义使用函数,则示例调用将无法按定义工作。

一个简化的例子:

int main( int argc, char **argv )
{
  float pct = 0.0
  if( !GetArgs(argc, argv, &pct) )
    DoStuff(pct)
}

int GetArgs( int argc, char **argv, float *thePct )
{
  extern char *optarg;
  int  rc = 0;

  (*thePct) = 50.0  /* default val */

  while( (opt = getopt(argc, argv, "hp:")) != -1 )
  {
    switch( opt )
    {
      case  'p':
            (*thePct) = atof( optarg );
            break;

      case  'h':
            MyUsage();  /* Explain everything */
            rc = -1;
            break;
    }
  }

  if( !rc )
  {
    rc = ValidatePct( (*thePct),   /* value to check */
                      0.0,         /* low pct val */
                      100.0 );     /* hi pct val */

    /* Other validations here */

    if( !rc )
      MyUsage();
  }
}

这将允许像这样的调用:

$ myprogram -p 45.0

如果您坚持使用解析器 getopt 和 getopt_long,您还可以创建带有选项的命令行,后跟 N 个其他参数,就像 grep 所做的那样,例如:

grep -in -e "SomeRegex" file1, file2, ..., fileN

出于纯粹的好奇,您您不是 PERL 程序员,是吗?

Assuming you are coding for Linux...

Try getopt_long (man 3 getopt_long) for the double-dash options.

Also, try making the validators to be generic functions and let getopt/getopt_long to the hard part of the parsing and checking required arguments to options.

In any case, if you want to use your functions as defined, your example call will not work as defined.

A simplified example:

int main( int argc, char **argv )
{
  float pct = 0.0
  if( !GetArgs(argc, argv, &pct) )
    DoStuff(pct)
}

int GetArgs( int argc, char **argv, float *thePct )
{
  extern char *optarg;
  int  rc = 0;

  (*thePct) = 50.0  /* default val */

  while( (opt = getopt(argc, argv, "hp:")) != -1 )
  {
    switch( opt )
    {
      case  'p':
            (*thePct) = atof( optarg );
            break;

      case  'h':
            MyUsage();  /* Explain everything */
            rc = -1;
            break;
    }
  }

  if( !rc )
  {
    rc = ValidatePct( (*thePct),   /* value to check */
                      0.0,         /* low pct val */
                      100.0 );     /* hi pct val */

    /* Other validations here */

    if( !rc )
      MyUsage();
  }
}

This will allow a call like:

$ myprogram -p 45.0

If you stick to the parsers getopt and getopt_long, you can also make command lines that take options followed by N number of other arguments like grep does, for instance:

grep -in -e "SomeRegex" file1, file2, ..., fileN

Out of sheer curiosity, you aren't a PERL programmer, are you?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文