2016-03-08 1 views
6

stdinから3つの整数を持つ行があるとします。それらを読み、解析する最も簡単な方法は何ですか? Pythonではa, b, c = map(int, input().split())のRustに相当し、Cではscanf("%d %d %d", &a, &b, &c);とは何ですか?失敗した場合でもstdinから複数のintを読み込む最も簡単な方法は何ですか?

私のようなものだったと思いついた最善の方法:

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

は簡単な方法はありますか?

答えて

6

あなたはこのためにtext_ioを使用することができます。

#[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もマクロscan!をサポートしています。

ファイルまたは一部から読みたい場合は
let (a, b, c): (i32, i32, i32); 
scan!("{}, {}, {}\n", a, b, c); 

他のソースであれば、どちらのマクロでも両方のマクロを使用できます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); 

または

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

コンパイラが文脈からこれらの型を推測できる場合は: i32 Sをオフに残すことができます。

免責事項:私はtext_ioの著者です。

+0

2番目の例をリッピングして申し訳ありませんが、これを開始しました;) –

9

あなたはこのためにscan-rulesを使用することができます。

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

あなたは少しより複雑な何かをしたい場合は、入力が一致しない場合、あなたは複数のルールと型推論を使用して、何をすべきかを指定することができます(デフォルトでは、それ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); 
     } 
    } 

免責事項:私はscan-rulesの著者です。

+0

テキスト1:1をリッピングして申し訳ありませんが、完璧なフィット感です; –

+0

うわー!それはあなたが持っている強力なマクロルールです。 –

関連する問題