What's the easiest way to read several ints from stdin if it's ok to fail?
You can use scan-rules
for this:
/*!
Add this to your `Cargo.toml`, or just run with `cargo script`:
```cargo
[dependencies]
scan-rules = "0.1.1"
```
*/
#[macro_use] extern crate scan_rules;
fn main() {
print!("Enter 3 ints: ");
readln! {
(let a: i32, let b: i32, let c: i32) => {
println!("a, b, c: {}, {}, {}", a, b, c);
}
}
}
If you want to do something a little more involved, you can use multiple rules and type inference, and specify what to do if the input doesn't match any of the rules given (by default it panic!
s):
readln! {
// Space-separated ints
(let a: i32, let b: i32, let c: i32) => {
println!("a b c: {} {} {}", a, b, c);
},
// Comma-separated ints, using inference.
(let a, ",", let b, ",", let c) => {
let a: i32 = a;
let b: i32 = b;
let c: i32 = c;
println!("a, b, c: {}, {}, {}", a, b, c);
},
// Comma-separated list of *between* 1 and 3 integers.
([let ns: i32],{1,3}) => {
println!("ns: {:?}", ns);
},
// Fallback if none of the above match.
(..line) => {
println!("Invalid input: {:?}", line);
}
}
Disclaimer: I am the author of scan-rules
.
You can use text_io
for this:
#[macro_use] extern crate text_io;
fn main() {
// reads until a whitespace is encountered
let a: i32 = read!();
let b: i32 = read!();
let c: i32 = read!();
}
text_io
0.1.3
also supports a scan!
macro:
let (a, b, c): (i32, i32, i32);
scan!("{}, {}, {}\n", a, b, c);
in case you want to read from a file or some other source, you can also use both macros on any type that implements Iterator<Item=u8>
:
use std::io::Read;
let mut file = std::fs::File::open("text.txt").unwrap()
.bytes()
.map(Result::unwrap);
let x: i32 = read!("{}\n", file);
or
let (x, y, z): (i32, i32, i32);
scan!(file => "{}, {}: {}", x, y, z);
You can leave off the : i32
s if the compiler can infer those types from context.
Disclaimer: I am the author of text_io
.