5

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?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jasiu
  • 2,674
  • 2
  • 27
  • 27
  • 3
    You are likely getting downvotes because it's expected to show that [you've made some effort](http://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users/261593#261593) to solve your problem *before* asking. As it is currently, your question looks [like this](http://odesk.ro/wp-content/uploads/2013/10/Quotes31.jpg). – Shepmaster Sep 11 '16 at 19:16
  • 1
    Related: [How do I parse a string to a list of floats using functional style?](http://stackoverflow.com/questions/19507730/how-do-i-parse-a-string-to-a-list-of-floats-using-functional-style) – Shepmaster Sep 11 '16 at 19:19
  • 2
    Related: [What's the easiest way to read several ints from stdin if it's ok to fail?](http://stackoverflow.com/q/35860264/155423) – Shepmaster Sep 11 '16 at 19:24

2 Answers2

12

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.

Aurora0001
  • 13,139
  • 5
  • 50
  • 53
  • 1
    For those who copy this code and get panic "thread 'main' panicked at 'Not an integer!: ParseIntError { kind: InvalidDigit }'", it may be helpful to replace split with split_whitespace. "\n" may appears in split function's result. – Yi Wang May 23 '22 at 13:36
5

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
bluss
  • 12,472
  • 1
  • 49
  • 48