Мне нужно проанализировать файл с каждой строкой
<string><space><int><space><float>
например.
abce 2 2.5
В C я бы сделал:
scanf("%s%d%f", &s, &i, &f);
Как я могу сделать это легко и идиоматично в Rust?
Мне нужно проанализировать файл с каждой строкой
<string><space><int><space><float>
например.
abce 2 2.5
В C я бы сделал:
scanf("%s%d%f", &s, &i, &f);
Как я могу сделать это легко и идиоматично в Rust?
Стандартная библиотека не предоставляет эту функцию. Вы можете написать свой собственный макрос.
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"))
}
Второй входной аргумент для макроса может быть a & str, char или соответствующей функцией закрытия /. Указанные типы должны реализовывать свойство FromStr.
Обратите внимание, что я поставил это вместе быстро, чтобы он не был протестирован полностью.
Вы можете использовать ящик text_io
для входа типа scanf, который имитирует макрос print!
в синтаксисе
#[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);
}
Вы также можете разбить его на 3 команды:
#[macro_use] extern crate text_io;
fn main() {
let a: String = read!("{} ");
let b: i32 = read!("{} ");
let c: f32 = read!("{}\n");
}
Ящик scan_fmt предлагает другую альтернативу. Он поддерживает простые шаблоны, возвращает свой вывод в параметрах и имеет синтаксис, который лучше всего подходит для 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());
}