Rust Command-Line Arguments
Most of the small projects worth building as practice — a to-do list, a word counter — need to take input from the command line rather than hardcoding values in the source. This page covers the basics.
Reading arguments with std::env::args
Section titled “Reading arguments with std::env::args”use std::env;
fn main() { let args: Vec<String> = env::args().collect(); println!("{:?}", args);}If you compiled this into a program called greet and ran:
./greet AliceYou’d see:
["greet", "Alice"]The first element is always the program’s own name — the arguments you actually typed start at index 1.
Reading a specific argument
Section titled “Reading a specific argument”use std::env;
fn main() { let args: Vec<String> = env::args().collect();
if args.len() < 2 { println!("Usage: greet <name>"); return; }
let name = &args[1]; println!("Hello, {name}!");}Run with cargo run -- Alice and you’d get:
Hello, Alice!Run it with no arguments, and you’d see the usage message instead of a crash — checking args.len() before indexing avoids a panic if someone forgets to pass anything.
Parsing an argument into a number
Section titled “Parsing an argument into a number”Since every argument comes in as a String, you’ll often need .parse() (from the Type Casting page) to turn one into a number:
use std::env;
fn main() { let args: Vec<String> = env::args().collect();
if args.len() < 2 { println!("Usage: square <number>"); return; }
match args[1].parse::<i32>() { Ok(n) => println!("{}", n * n), Err(_) => println!("That's not a valid number"), }}For anything more than a couple of arguments: use clap
Section titled “For anything more than a couple of arguments: use clap”Manually indexing into args gets unwieldy fast once you need flags (--verbose), optional values, or helpful --help output. The standard solution is the clap crate, added with:
cargo add clap --features deriveuse clap::Parser;
#[derive(Parser)]struct Args { name: String,
#[arg(short, long, default_value_t = 1)] count: u32,}
fn main() { let args = Args::parse(); for _ in 0..args.count { println!("Hello, {}!", args.name); }}This gives you argument parsing, validation, and a working --help message, all generated from the struct definition. You don’t need clap for quick scripts, but for anything you’ll actually use more than once, it saves a lot of manual work.
std::env::args().collect()gives you aVec<String>of the command-line arguments; index 0 is always the program name.- Check
args.len()before indexing, so a missing argument doesn’t panic your program. .parse()turns aStringargument into a number, same as elsewhere.- For anything beyond a couple of plain arguments, the
clapcrate is the standard, well-worn choice.
Quick check
Section titled “Quick check”Quick check
1. When you call env::args().collect(), what is the first element of the resulting Vec?
2. Why check args.len() before indexing into args?
3. What does the clap crate give you that manual args indexing doesn't?
Score: 0 / 3