Does Rust have something like scanf?

I need to parse a file with each line

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

eg.

 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?

+11
string parsing rust
source share
3 answers

The standard library does not provide this function. You can write your own 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 corresponding closing function /. The specified types must implement the FromStr property.

Please note that I put this together quickly so that it is not fully tested.

+13
source share

You can use the text_io box to type scanf, which mimics the print! macro print! in the 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 break it into 3 teams:

 #[macro_use] extern crate text_io; fn main() { let a: String = read!("{} "); let b: i32 = read!("{} "); let c: f32 = read!("{}\n"); } 
+8
source share

The scan_fmt box offers another alternative. It supports simple patterns, returns its output in parameters, and has the syntax that works best for text_io :

 #[macro_use] extern crate scan_fmt; fn main() { let (s, i, j) = scan_fmt!("abce 2 2.5", "{} {d} {f}\n", String, i32, f32); println!("{} {} {}", s.unwrap(), i.unwrap(), j.unwrap()); } 
0
source share

All Articles