🎓 A1Learner
🔍

Rust Command Line Arguments

Command line arguments are the words after a program's name in a typed command, like cargo run. A program can read those words.

Collect the words into a Vec

env::args() gives the words typed after your program's name one by one, as text. Use .collect() to gather them. Write the type out, too. collect can build many kinds of collection. Rust cannot guess which one you want:

use std::env;

let args: Vec<String> = env::args().collect();

The first word is the program itself

args[0] is the program's own name or path. Your real arguments start at args[1]:

let query = &args[1];
let file_path = &args[2];

Give a Cargo program its arguments

Run a Cargo program with its own arguments after -- : the words after it go to your program, not to Cargo.

cargo run -- to poem.txt

Or take the words one by one

Reading args[1] when no argument was given panics with index out of bounds. Stepping with next() hands you a None to handle instead:

let mut words = env::args();
let _program = words.next(); // skip the program name
let query = words.next();    // Some(word), or None

Match small commands by hand

Match on args.len() and on the words themselves. One argument can be a word to check. Two can be a command plus a number. The hand-rolled style works until a tool outgrows it. Run with the two arguments hello and 3, this prints:

match args.len() {
    2 => println!("checking the word {}", args[1]),
    3 => println!("{} repeated {} times", args[1], args[2]),
    _ => println!("usage: wordcheck <word> [times]"),
}

Example

use std::env;
fn main() {
    let args: Vec<String> = env::args().collect();
    let query = &args[1];
    let file_path = &args[2];
    println!("Searching for {query}");
    println!("In file {file_path}");
}

Key points

  • For real tools, use the clap crate instead of matching by hand.
  • Real tools have flags, help text and subcommands.
  • clap parses the arguments and checks them.
  • It prints a usage message on mistakes.
  • Command line arguments are the words typed after a program's name, and the program reads them as its input words.

In this example, the program is run with two arguments: to and poem.txt. In a Cargo project you would type cargo run -- to poem.txt. env::args() gives the program's path first, then to, then poem.txt. collect() gathers all three into a Vec<String>. The code borrows args[1] as query and args[2] as file_path, skipping args[0], the program itself. The two println! lines then show the job the program was given: Searching for to, In file poem.txt.

Note

env::args() panics if an argument is not valid Unicode text.

Programs that must accept any bytes use env::args_os() instead, which gives OsString values.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

After env::args().collect(), what is stored in args[0]?