Rustで100本ノック: 文字列を数値にする話
本日の100本ノックメモ2本目、文字列を数値にしたいということで、このあたりはNo.5とかで登場してきました。
いわゆる型変換はasを使って行えることはそれなりにわかってます。
let f = 3u8 as f32; // 整数をf32へ
だからといって、文字列を直接数値変換するのは存在しませんのでエラーになります。
この辺りはPythonやRubyならありそうなものですが、文字列をメモリ上に直接保有するような構造のため、簡単にはできないんでしょうね。んじゃ、String型(?)を生成したら、変換メソッドでもあるんかな?
見つからない気がする。ということでググってみる。え、やっぱりStringにあったのか!
String型のメソッドparse()で対応できるのね。とはいえ、parse()自体特定の方に変換するメソッドでは無く、受け側の型に対応して内部処理を行うみたいです。そのため、型推論は使えません。受け側変数の型を明示することで動くようです。
で、変換処理は失敗する可能性(アルファベットをうっかり変換しちゃった、等)もあるのかResultが戻っているのでチェック必須ですね。
let s100: u8 = String::from("100").parse().expect("変換できませんでした");
let n100 = 3u8 as f32;
println!("{} {}", s100, n100);
という感じでそれぞれ変換できますね。これで文字列を受け取って変換できる。
use std::io;
fn main() {
println!("何か入力を");
let mut data = String::new();
io::stdin().read_line(&mut data).expect("入力中に異常がありました");
let data: u32 = data.parse().expect("変換できない文字列でした");
println!("{}", data);
}
え? 変換に失敗?なぜだ?ちゃんと数字だけなのに。なにか非数のコードが入ってるんだろうな。入力された123という文字列を見てみたい。
ということでデバッグの設定をして試してみました。
あ、なるほど改行コードか。てことは行末の改行コードの類いを消さないといけないということになるのかな。trim()とかchomp()とかあるんかな。trim()があったので使ってみました。
改行コードが消えて、今度はエラー無くできました。もちろん文字列に英数字を含めればexpect()によりエラー処理で止まってくれます。LLVMによるアセンブラコードがいきなり目に入るのでちょっと怖い(ぉぃ
そっか、文字列の取り込み時に改行コードも込み込みで入ってしまってるというのが要因だったのね。ざっくりコードを修正しておくと、こんな感じになりそうです。
use std::io;
fn main() {
println!("何か入力を");
let mut data = String::new();
io::stdin().read_line(&mut data).expect("入力中に異常がありました");
let data: u32 = data.trim().parse().expect("変換できない文字列でした");
println!("{}", data);
}
後半では数値入力を複数させてるようなので、これを関数にした方が良さそうですね。
この記事が気に入ったらサポートをしてみませんか?