###はじめに
単純に面白そうという興味からRust言語を勉強し始めたのですが、成果が見えるとやっぱりモチベーションがあがるので、AtCoderとかの競技プログラミングで使ってみたいと思いました。ここで問題になるのが標準入力、なにせめちゃくちゃ冗長でネットの記事にも「これだ!」とピンとくるのが無く途方に暮れていました。なので作りました、Pythonのinput関数っぽく。まだ本格利用していないのでRustaceanの方はいろいろ改造してください。そして私に教えて。
###環境
> rustc --version rustc 1.39.0 (4560ea788 2019-11-04)
###この記事の内容
1.作ったもの
2.軽い解説
###成果物
fn input() -> String{
let mut buf = String::new(); //A
std::io::stdin().read_line(&mut buf).unwrap(); //B
buf.trim().to_string() //C
}
fn main(){
let s = &input();
println!("{}", s);
}
###解説
input関数は引数なしで標準入力をString型で返します。
A. mut String型としてbuf
を定義する。
B. read_line
の一連の流れでbuf
に標準入力を格納する。
C. trim
を用いて空白とかを除去して返却する。
String型として明確なので&input()とすると&str型として扱うこともできます。
###What is "trim()" ?
「このtrim()ってなんだよ。こいついる?」と思った方はもう少しお付き合いください。
皆様はどのような環境でRustを実行されていますでしょうか?上のrustc --version
を見ればわかるかもしれませんが私はWindows10環境で実行しております。
実験としてtrim()を外した状態の関数で以下のようなソースコードを作ります。
fn input() -> String{
let mut buf = String::new();
std::io::stdin().read_line(&mut buf).unwrap();
buf.to_string()
}
fn main(){
let s = input();
let mut i = 0;
for c in s.as_str().chars(){
println!("{} : {} ({})", i, c, c as u8);
i += 1
}
}
標準入力にhello
と入力します。
PS> ./input_test.rs
hello
0 : h (104)
1 : e (101)
2 : l (108)
3 : l (108)
4 : o (111)
(13)
6 :
(10)
??
理想としてはhelloのところだけ表示してほしいのですが13と10という謎の記号が出力されておりこれではようわかりません。
ちなみにwslのubuntu(rustc 1.38.0 (625451e37 2019-09-23)
)で同じソースをコンパイルし実行すると以下のようになります。
$ ./main_rs
hello
0 : h (104)
1 : e (101)
2 : l (108)
3 : l (108)
4 : o (111)
5 :
(10)
おわかりいただけただろうか?
この最後に出力されてた記号はラインフィード(10)とキャリッジリターン(13)で、親切なことにread_lineではここまで読み込んでしまう上に、windowsとlinuxだと改行の仕様がちょっと違うのでこうなってしまう。
このOS間の差を埋めるためにtrim()を用いて空白文字を削除しているのである。
###おわりに
「Rustの標準入力について調べていたら改行文字の話がはじまってた…」という感じになったらごめんなさい。自分が実際にはまりかけた所を共有して少しでも何かの役に立てたら良いなという程度の記事です。ここまで読んでくださって本当にありがとうございました。
ちなみに私はread_lineにはunwrapじゃなくてexpectを使った方が良いと思います。