見出し画像

Rustで100本ノック: 文字列を数値にする話

本日の100本ノックメモ2本目、文字列を数値にしたいということで、このあたりはNo.5とかで登場してきました。

いわゆる型変換はasを使って行えることはそれなりにわかってます。

let f = 3u8 as f32; // 整数をf32へ

だからといって、文字列を直接数値変換するのは存在しませんのでエラーになります。

画像1

この辺りはPythonやRubyならありそうなものですが、文字列をメモリ上に直接保有するような構造のため、簡単にはできないんでしょうね。んじゃ、String型(?)を生成したら、変換メソッドでもあるんかな?

画像2

見つからない気がする。ということでググってみる。え、やっぱり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);
}

画像3

え? 変換に失敗?なぜだ?ちゃんと数字だけなのに。なにか非数のコードが入ってるんだろうな。入力された123という文字列を見てみたい。

ということでデバッグの設定をして試してみました。

画像4

あ、なるほど改行コードか。てことは行末の改行コードの類いを消さないといけないということになるのかな。trim()とかchomp()とかあるんかな。trim()があったので使ってみました。

画像5

改行コードが消えて、今度はエラー無くできました。もちろん文字列に英数字を含めればexpect()によりエラー処理で止まってくれます。LLVMによるアセンブラコードがいきなり目に入るのでちょっと怖い(ぉぃ

画像6

そっか、文字列の取り込み時に改行コードも込み込みで入ってしまってるというのが要因だったのね。ざっくりコードを修正しておくと、こんな感じになりそうです。

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

後半では数値入力を複数させてるようなので、これを関数にした方が良さそうですね。

この記事が気に入ったらサポートをしてみませんか?