2016-03-08 3 views
6

Angenommen, ich erwarte eine Zeile mit 3 ganzen Zahlen von stdin. Was ist der einfachste Weg, sie zu lesen und zu analysieren? Was ist das Rust-Äquivalent von a, b, c = map(int, input().split()) in Python oder scanf("%d %d %d", &a, &b, &c); in C?Was ist der einfachste Weg, mehrere Ints von stdin zu lesen, wenn es in Ordnung ist, zu versagen?

Der beste Weg, ich kam mit war so etwas wie:

let mut line = String::new(); 
io::stdin().read_line(&mut line).unwrap(); 
let parts: Vec<&str> = line.split_whitespace().collect(); 
let a: i32 = parts[0].parse().unwrap(); 
let b: i32 = parts[1].parse().unwrap(); 
let c: i32 = parts[2].parse().unwrap(); 

Gibt es einen einfacheren Weg?

Antwort

6

Sie können text_io für diesen Einsatz:

#[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_io0.1.3 unterstützt auch ein scan! Makro:

let (a, b, c): (i32, i32, i32); 
scan!("{}, {}, {}\n", a, b, c); 

falls Sie aus einer Datei lesen wollen oder einige andere Quelle, Sie können auch beide Makros für alle verwenden Typ, der Iterator<Item=u8> implementiert:

use std::io::Read; 
let mut file = std::fs::File::open("text.txt").unwrap() 
               .bytes() 
               .map(Result::unwrap); 
let x: i32 = read!("{}\n", file); 

oder

let (x, y, z): (i32, i32, i32); 
scan!(file => "{}, {}: {}", x, y, z); 

Sie können weglassen die : i32 s, wenn der Compiler diese Typen aus dem Kontext ableiten kann.

Haftungsausschluss: Ich bin der Autor von text_io.

+0

Entschuldigung für das Rippen Ihres zweiten Beispiels, aber Sie haben das angefangen;) –

9

Sie scan-rules dafür verwenden können:

/*! 
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); 
     } 
    } 
} 

Wenn Sie etwas ein wenig komplizierter machen möchten, können Sie mehrere Regeln und Typinferenz, und festlegen, was passiert, wenn der Eingang nicht mit tun eine der angegebenen Regeln (standardmäßig es panic! e):

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); 
     } 
    } 

Haftungsausschluss: ich bin der Autor des scan-rules.

+0

Entschuldigung für das Rippen Ihres Textes 1: 1, aber es ist nur eine perfekte Passform;) –

+0

Wow! Das ist eine mächtige Magie, die du dort hast. –

Verwandte Themen