< 返回版块

2019-05-31 11:39    责任编辑:jay

标签:Tyro,Novice

args

 use std::env;

 fn main() {
   // env::args returns an iterator over the parameters
   println!("Got following parameters: ");
   for arg in env::args() {
     println!("- {}", arg);
   }

   // We can access specific parameters using the iterator API
   let mut args = env::args();
   if let Some(arg) = args.nth(0) {
     println!("The path to this program is: {}", arg);
   }
   if let Some(arg) = args.nth(1) {
       println!("The first parameter is: {}", arg);
   }
   if let Some(arg) = args.nth(2) {
       println!("The second parameter is: {}", arg);
   }

   // Or as a vector
   let args: Vec<_> = env::args().collect();
   println!("The path to this program is: {}", args[0]);
   if args.len() > 1 {
       println!("The first parameter is: {}", args[1]);
   }
   if args.len() > 2 {
       println!("The second parameter is: {}", args[2]);
   }
 }
 
 // cargo run --bin cli_params some_option some_other_option:

第三方工具:

A tools for serious command-line utility: clap

Cargo.toml: clap = "2.33.0"

 // (Full example with detailed comments in examples/01b_quick_example.rs)
 //
 // This example demonstrates clap's full 'builder pattern' style of creating arguments which is
 // more verbose, but allows easier editing, and at times more advanced options, or the possibility
 // to generate arguments dynamically.
 extern crate clap;
 use clap::{Arg, App, SubCommand};

 fn main() {
     let matches = App::new("My Super Program")
                           .version("1.0")
                           .author("Kevin K. <[email protected]>")
                           .about("Does awesome things")
                           .arg(Arg::with_name("config")
                                .short("c")
                                .long("config")
                                .value_name("FILE")
                                .help("Sets a custom config file")
                                .takes_value(true))
                           .arg(Arg::with_name("INPUT")
                                .help("Sets the input file to use")
                                .required(true)
                                .index(1))
                           .arg(Arg::with_name("v")
                                .short("v")
                                .multiple(true)
                                .help("Sets the level of verbosity"))
                           .subcommand(SubCommand::with_name("test")
                                       .about("controls testing features")
                                       .version("1.3")
                                       .author("Someone E. <[email protected]>")
                                       .arg(Arg::with_name("debug")
                                           .short("d")
                                           .help("print debug information verbosely")))
                           .get_matches();

     // Gets a value for config if supplied by user, or defaults to "default.conf"
     let config = matches.value_of("config").unwrap_or("default.conf");
     println!("Value for config: {}", config);

     // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't
     // required we could have used an 'if let' to conditionally get the value)
     println!("Using input file: {}", matches.value_of("INPUT").unwrap());

     // Vary the output based on how many times the user used the "verbose" flag
     // (i.e. 'myprog -v -v -v' or 'myprog -vvv' vs 'myprog -v'
     match matches.occurrences_of("v") {
         0 => println!("No verbose info"),
         1 => println!("Some verbose info"),
         2 => println!("Tons of verbose info"),
         3 | _ => println!("Don't be crazy"),
     }

     // You can handle information about subcommands by requesting their matches by name
     // (as below), requesting just the name used, or both at the same time
     if let Some(matches) = matches.subcommand_matches("test") {
         if matches.is_present("debug") {
             println!("Printing debug info...");
         } else {
             println!("Printing normally...");
         }
     }

     // more program logic goes here...
 }

Other:

  use std::io;
  use std::io::prelude::*;

  fn main() {
    print_single_line("Please enter your forename: ");
    let forename = read_line_iter();

    print_single_line("Please enter your surname: ");
    let surname = read_line_buffer();

    print_single_line("Please enter your age: ");
    let age = read_number();

    println!(
      "Hello, {} year old human named {} {}!",
      age, forename, surname
    );
  }

  fn print_single_line(text: &str) {
    // We can print lines without adding a newline
    print!("{}", text);
    // However, we need to flush stdout afterwards
    // in order to guarantee that the data actually displays
    io::stdout().flush().expect("Failed to flush stdout");
  }

  fn read_line_iter() -> String {
    let stdin = io::stdin();
    // Read one line of input iterator-style
    let input = stdin.lock().lines().next();
    input
      .expect("No lines in buffer")
      .expect("Failed to read line")
      .trim()
      .to_string()
  }

  fn read_line_buffer() -> String {
    // Read one line of input buffer-style
    let mut input = String::new();
    io::stdin()
      .read_line(&mut input)
      .expect("Failed to read line");
    input.trim().to_string()
  }

  fn read_number() -> i32 {
    let stdin = io::stdin();
    loop {
      // Iterate over all lines that will be inputted
      for line in stdin.lock().lines() {
        let input = line.expect("Failed to read line");
        // Try to convert a string into a number
        match input.trim().parse::<i32>() {
          Ok(num) => return num,
            Err(e) => println!("Failed to read number: {}", e),
        }
      }
    }
  }