Skip to content

Commit 73f72cc

Browse files
authored
Merge pull request #49 from yuk1ty/add-sec3_6_2
add 3.6.2
2 parents 782e30a + ba977cd commit 73f72cc

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

chapter3/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,6 @@ path = "src/3_6_1/main.rs"
5050
[[bin]]
5151
name = "3_6_3"
5252
path = "src/3_6_3/main.rs"
53+
[[bin]]
54+
name = "3_6_2"
55+
path = "src/3_6_2/main.rs"

chapter3/src/3_6_2/main.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//! Rust には scanf 関数はない。したがって、この節は本来は実装できない。
2+
//! Rust のマクロを使用すると scanf に近い実装を作ることができるので、参考程度に実装しておく。
3+
//! マクロを自前実装する以外の選択肢としては、下記のようなクレートを使用する手もある。
4+
//! - [text_io](https://github.com/oli-obk/rust-si): scan マクロが存在する。
5+
//! - [scan_fmt](https://github.com/wlentz/scan_fmt): 同様に scan_fmt マクロが存在する。
6+
7+
/// scan! マクロ。
8+
/// scan!("<入れた文字>", セパレータの設定, 型情報*) と値を入れていくと、scanf とほぼ同等の動きをする。
9+
///
10+
/// Example:
11+
/// ```rust
12+
/// scan!("123 text", char::is_whitespacce, i32, String);
13+
/// ```
14+
macro_rules! scan {
15+
( $string:expr, $sep:expr, $( $x:ty ),+ ) => {{
16+
let mut iter = $string.split($sep);
17+
($(iter.next().map(|word| word.parse::<$x>().ok().expect(&format!("couldn't parse {}", word))).unwrap(),)*)
18+
}}
19+
}
20+
21+
const SOURCE: &str = "123 1.234 1.0e4 test";
22+
23+
fn main() {
24+
let (i, f, g, s) = scan!(SOURCE, char::is_whitespace, i32, f64, f64, String);
25+
println!("i={} f={} g={} s={}", i, f, g, s);
26+
}

0 commit comments

Comments
 (0)