2015-06-25 13 views
7

Ho bisogno di analizzare un file con su ogni rigaRust ha qualcosa come scanf?

<string><space><int><space><float> 

esempio

abce 2 2.5 

In C avrei fatto:

scanf("%s%d%f", &s, &i, &f); 

Come posso fare questo in modo semplice e idiomaticamente a Rust?

risposta

10

I doesn libreria standard Fornire questa funzionalità. Puoi scrivere il tuo con una macro.

macro_rules! scan { 
    ($string:expr, $sep:expr, $($x:ty),+) => {{ 
     let mut iter = $string.split($sep); 
     ($(iter.next().and_then(|word| word.parse::<$x>().ok()),)*) 
    }} 
} 

fn main() { 
    let output = scan!("2 false fox", char::is_whitespace, u8, bool, String); 
    println!("{:?}", output); // (Some(2), Some(false), Some("fox")) 
} 

Il secondo argomento ingresso alla macro può essere un & str, char, o la chiusura/funzione appropriata. I tipi specificati devono implementare il tratto FromStr.

Si noti che ho messo insieme questo rapidamente in modo che non è stato testato a fondo.

6

È possibile utilizzare la cassa text_io per l'input scanf-like che imita la macro print! nella sintassi

#[macro_use] extern crate text_io; 

fn main() { 
    // note that the whitespace between the {} is relevant 
    // placing any characters there will ignore them but require 
    // the input to have them 
    let (s, i, j): (String, i32, f32); 
    scan!("{} {} {}\n", s, i, j); 
} 

Si può anche dividere in 3 comandi ciascuno:

#[macro_use] extern crate text_io; 

fn main() { 
    let a: String = read!("{} "); 
    let b: i32 = read!("{} "); 
    let c: f32 = read!("{}\n"); 
} 
+0

Sembra che non sia più necessario 'funzione (plugin)'? – Shepmaster

+0

Ho aggiornato gli esempi alla versione corrente –