Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Rust have anything like scanf?

Tags:

I need to parse a file with on each line

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

e.g.

abce 2 2.5 

In C I would do:

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

How can I do this easily and idiomatically in Rust?

like image 879
Peter Smit Avatar asked Jun 25 '15 09:06

Peter Smit


2 Answers

The standard library doesn't provide this functionality. You could write your own with a 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")) } 

The second input argument to the macro can be a &str, char, or the appropriate closure / function. The specified types must implement the FromStr trait.

Note that I put this together quickly so it hasn't been tested thoroughly.

like image 120
A.B. Avatar answered Sep 18 '22 08:09

A.B.


You can use the text_io crate for scanf-like input that mimicks the print! macro in syntax

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

You can also split it into 3 commands each:

#[macro_use] extern crate text_io;  fn main() {     let a: String = read!("{} ");     let b: i32 = read!("{} ");     let c: f32 = read!("{}\n"); } 
like image 44
oli_obk Avatar answered Sep 17 '22 08:09

oli_obk