【问题标题】:Parsing command line flags with arguments using docopt and Rust, similar to getopt使用 docopt 和 Rust 解析带有参数的命令行标志,类似于 getopt
【发布时间】:2016-04-13 21:09:37
【问题描述】:

我正在寻找一种方法来模拟 C 如何使用 getopt。我想使用 docopt 将以下 C sn-p 转换为 Rust。我似乎无法将标志传递给命令行参数:

char in;
char* stringName;
while(( in = getopt( argc, argv, "a:b:c:d:e:")) != EOF) {
    switch(in) {
        case 'a':
            stringName = optarg;
            break;
     // ... and so on

那我想跑

cargo run -a "hello" -b 3 ... and so on

到目前为止我已经写了这个:

extern crate rustc_serialize;
extern crate docopt;

use docopt::Docopt;

// Define a USAGE string
const USAGE: &'static str = "
Program.

Usage: [options] [<value1>] [options] [<value2>] [options] [<value3>] [options] [<value4>]

Options:
    -a, 
    -b, 
    -c,
    -d,  
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_value1: Option<String>,
    flag_a: bool,
    flag_b: bool,
    flag_c: bool,
    arg_value2: Option<String>,
    arg_value3: Option<String>,
    arg_value4: Option<String>,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());
    println!("{:?}", args);
}

当我cargo run 我得到

未知标志-a

【问题讨论】:

  • 请显示您尝试过的代码以及您遇到的问题
  • @ker 我已将其添加到编辑中
  • 我不认为你的 docopt 规范做你认为它做的事情。您怎么知道为哪个值设置了哪个标志?您获得的 Args 结构对于 program -a "hi" -b 2program -b "hi" -a 2 具有相同的值
  • @ker 好的,我知道它有什么问题。
  • 然而,还有另一个问题。你提到你使用cargo run,对吧?为了让它正确地将参数传递给程序,您需要在双破折号后指定它们,如下所示:cargo run -- -a "hi" -b 2。否则cargo run 将无法决定哪些选项针对自身以及哪些针对程序。但无论如何,@ker 的担忧是绝对有道理的。坦率地说,我不确定是否有任何参数解析库可以做你想要的(最多四个参数,每个参数都有不同的标志)。您可能需要自己实现解析。

标签: rust docopt


【解决方案1】:

这样的事情可能会让你非常接近:

const USAGE: &'static str = "
Program.

Usage: program [options]

Options:
    -a VALUE
    -b VALUE
    -c VALUE
    -d VALUE
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_a: Option<String>,
    flag_b: Option<i32>,
    flag_c: Option<String>,
    flag_d: Option<String>,
}

使用cargo run -- -a "hello" -b 3 运行时(见下面的注释),输出为:

Args { flag_a: Some("hello"), flag_b: Some(3), flag_c: None, flag_d: None }

然后,您可以在 flag_a 上进行模式匹配,以判断它是否已提供(从而获取值)。不需要单独的布尔标志,Option 在这种情况下会更好。


作为Vladimir Matveev points out,当您通过cargo run 执行程序时,您必须区分cargo 的参数和程序的参数。大多数(全部?)执行此操作的程序都使用特殊标志--。这将程序之间的参数分开。您也可以在程序构建后直接运行:

$ cargo build
$ ./target/debug/program_name -a "hello" -b 3 

【讨论】:

  • 这是非常有用的。因此,每当您解析使用标志的命令行参数时,您必须始终使用 -- 作为第一个命令行参数?
  • @BumptheTrump 不,这不太正确。我添加了一条注释。
猜你喜欢
  • 1970-01-01
  • 2016-01-11
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
  • 2013-03-06
  • 2010-10-19
  • 2022-07-04
  • 2021-03-14
相关资源
最近更新 更多