Jasiu
Jasiu

Reputation: 2734

How do I read multiple integers from a single line of stdin?

To learn Rust, I'm looking at things like the HackerRank 30 days challenge, Project Euler, and other programming contests. My first obstacle is to read multiple integers from a single line of stdin.

In C++ I can conveniently say:

cin >> n >> m;

How do I do this idiomatically in Rust?

Upvotes: 7

Views: 6192

Answers (2)

bluss
bluss

Reputation: 13792

You can use the scan-rules crate (docs), which makes this kind of scanning easy (and has features to make it powerful too).

The following example code uses scan-rules version 0.1.3 (file can be ran directly with cargo-script).

The example program accepts two integers separated by whitespace, on the same line.

// cargo-deps: scan-rules="^0.1"

#[macro_use]
extern crate scan_rules;

fn main() {
    let result = try_readln! {
        (let n: u32, let m: u32) => (n, m)
    };
    match result {
        Ok((n, m)) => println!("I read n={}, m={}", n, m),
        Err(e) => println!("Failed to parse input: {}", e),
    }
}

Test runs:

4  5
I read n=4, m=5

5 a
Failed to parse input: scan error: syntax error: expected integer, at offset: 2

Upvotes: 5

Aurora0001
Aurora0001

Reputation: 13567

The best way, as far as I know, is just to split the input line and then map those to integers, like this:

use std::io;

let mut line = String::new();
io::stdin().read_line(&mut line).expect("Failed to read line");

let inputs: Vec<u32> = line.split(" ")
    .map(|x| x.parse().expect("Not an integer!"))
    .collect();

// inputs is a Vec<u32> of the inputs.

Be aware that this will panic! if the input is invalid; you should instead handle the result values properly if you wish to avoid this.

Upvotes: 11

Related Questions