RustArena

Step 5 of 7

Several values on one line: split_whitespace

Input often packs several values on one line: 3 4, ana 92, move 10 -5. split_whitespace() cuts a string into pieces wherever there's whitespace:

fn main() {
    let line = "  move   10 -5\n";
    for part in line.split_whitespace() {
        println!("[{part}]");
    }
    println!("{} parts", line.split_whitespace().count());
}
[move]
[10]
[-5]
3 parts

Numbers from one line

Parse each piece and collect the numbers in a Vec:

use std::io;

fn main() {
    let mut line = String::new();
    io::stdin().read_line(&mut line).expect("failed to read a line");
    let mut nums = Vec::new();
    for part in line.split_whitespace() {
        let n: i32 = part.parse().expect("not a number");
        nums.push(n);
    }
    println!("{} numbers: {:?}", nums.len(), nums);
    println!("first + last = {}", nums[0] + nums[nums.len() - 1]);
}
4 8 15 16 23 42
6 numbers: [4, 8, 15, 16, 23, 42]
first + last = 46

When the format says there are exactly two values (like width height), read them as nums[0] and nums[1]. If a line has fewer values than expected, the index is out of bounds and the program panics; that's acceptable for input you trust, and step 7 shows how to handle input you don't.

You'll often see the loop above written in iterator style, which you'll learn in modules 26 and 27:

let nums: Vec<i32> = line.split_whitespace().map(|p| p.parse().expect("not a number")).collect();

Why not split(' ')?

split(' ') cuts at every single space. Two spaces in a row produce an empty piece "" between them, and parsing "" fails:

fn main() {
    let line = "3  4";
    for part in line.split(' ') {
        println!("[{part}]");
        let n: i32 = part.parse().expect("not a number");
        println!("{n}");
    }
}
[3]
3
[]

The panic message: not a number: ParseIntError { kind: Empty }. For values separated by whitespace, split_whitespace is the right tool. (split(',') is right for comma-separated values; module 18 covers splitting in depth.)

Common mistakes

Your task

One line holds a rectangle's width and height, separated by whitespace. Print its area and perimeter:

area: 12
perimeter: 14

Challenge 2

One line holds one or more whole numbers (possibly negative). Print how many there are, the smallest and the largest:

count: 5, min: -2, max: 9

Challenge 3

Each line holds a player's name and a whole-number score (possibly negative), like ana 92. Read lines until the end of the input and print the best player. If two players tie, keep the one that came first:

best: cy with 95

Previous: Reading every line until the end Next: Reading all the input at once