Prompt
Rustでターミナルからの標準入力!
ターミナルからの標準入力(Standard Input)だね!
C言語の scanf や Javaの Scanner に慣れていると、Rustの標準入力は「ちょっと手順が多いな?」と感じるかもしれない。でも、それはRustが**「エラーの可能性」と「バッファリング(効率)」**を真剣に考えているからなんだ!
基本のキから、実用的なパターンまで一気に解説するよ!
1. 📝 最も基本的な読み込み(一行読み)
標準ライブラリの std::io を使うよ。
Rust
use std::io;
fn main() {
println!("何か入力してね:");
// 1. 入力を格納するための可変な String を用意
let mut input = String::new();
// 2. 標準入力のハンドルを取得して、一行読み込む
io::stdin()
.read_line(&mut input)
.expect("読み込みに失敗しました");
// 3. 末尾の改行コード(\n や \r\n)を削除
let input = input.trim();
println!("君が入力したのは: {}", input);
}💡 ここが「ややややこしい」ポイント
-
&mut input:read_lineは文字列を書き換えるので、可変な参照を渡す必要があるよ。 -
.expect(): 標準入力が閉じられていたり、不正なデータが来たりした時のエラー処理を強制されるんだ(Rustらしいね!)。 -
.trim():read_lineは改行文字も一緒にバッファに入れるから、これを取り除かないと後の比較や数値変換でハマるぞ!
2. 🔢 数値として読み込む
文字列として読み込んだ後に、parse を使って型変換するよ。
Rust
let mut input = String::new();
io::stdin().read_line(&mut input).ok();
// 文字列を u32 型にパース!
let age: u32 = input.trim().parse().expect("数字を入れてね!");3. 🚀 爆速で読み込む(競プロ・大量データ用)
情報工学を学ぶ君なら知っておきたい「効率」の話。
実は io::stdin().read_line() を毎回呼ぶのは、毎回ロックを取得するので少し遅いんだ。大量のデータを読み込むときは、BufReader を使うのがセオリーだよ!
Rust
use std::io::{self, BufRead};
fn main() {
let stdin = io::stdin();
// ロックを固定してバッファリングする
let mut reader = stdin.lock().lines();
if let Some(Ok(line)) = reader.next() {
println!("読み込んだ行: {}", line);
}
}⚠️ 見落とされがちな落とし穴:改行コードの違い
君は Windows 11 をメインに使っているよね?
Windowsの改行コードは \r\n (CRLF) だけど、Ubuntu(Linux)は \n (LF) だ。
trim() を使えば両方きれいに消えるけど、もし自分で pop() を使って最後の1文字だけ消そうとすると、Windows環境では \r が残ってしまい、文字列比較が意図通りに動かない……なんていう「OSの壁」にぶつかることがある。「標準入力には trim()」。これを合言葉にしよう!
🛠️ もっと楽にやりたいなら?
「いちいち read_line して parse するの面倒くさい!」という時は、proconio や text_io といった外部クレートを使うと、他言語の scanf みたいに書けるようになるよ。
Rust
// text_io クレートの例
let i: i32 = read!();