今日の内容
- コマンドライン引数とは
- ツール作成
はじめに
前回はif letについて学びました。
今回はコマンドライン引数について学びます。
コマンドライン引数とは
コマンドライン引数とは、プログラムを実行する際に、プログラム名の後に渡すデータのことを指します。
標準入力との違い
標準入力は、プログラム実行中にユーザーから入力を受け取る仕組みです。ターミナルで実行中のプログラムが入力待ち状態になることがあります。
これに対してコマンドライン引数は、プログラム実行時に渡されます。
値の受け取り方法
std::env::args
または、外部クレートを使う方法もあります。
実際にコマンドライン引数を渡す方法は、cargo run
する際に、例えば「1, 2, 3」を渡したければ以下のようにします。
cargo run 1 2 3
例: コマンドライン引数を表示するプログラム
fn main() {
let args = std::env::args();
println!("{:?}", args);
}
例えば、cargo run
する際に、「cargo run 1 2 3」と入力すると、以下の出力を得ることができます
Args { inner: ["target\\debug\\cmd_input.exe", "1", "2", "3"] }
注意点
上の例の実行結果を見てください。第一引数は"1"ではありません。
コマンドライン引数の取得において、 第一引数はプログラムの実行ファイル名 になります。
また、そのままだと要素はイテレータになるので、普通はベクタに変換して扱います。
ベクタに変換する方法は簡単で、collect
関数を利用します。
fn main() {
let args: Vec<String> = std::env::args().collect();
println!("{:?}", args);
}
/******** 実行結果 ********
["target\\debug\\cmd_input.exe", "1", "2", "3"]
*************************/
ベクタに変換することで、要素を指定して取り出すことが容易にできます。
ツールを作ろう
コマンドライン引数を利用してツールを作ってみましょう。
今回は「ファイル内容を読み取って文字数や行数をカウントするツール」を作成します。
コマンドライン引数には読み取るファイル名を与えます。
読み取ったファイルの「ファイル名」、「行数」、「文字数」を出力します。
use std::{env, fs, io::Read};
//行数カウント
fn lines(content: &String) -> u32 {
let mut lines: u32 = 1;
for c in content.chars() { if c == '\n' { lines += 1 } }
lines
}
//文字数カウント
fn chars(content: &String) -> u32 {
let mut chars: u32 = 0;
for c in content.chars() { if c != '\n' && c != '\r' { chars += 1 } }
chars
}
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 2 { panic!("Specify the file name!"); }
let file_result = fs::File::open(&args[1]);
if let Ok(mut file) = file_result {
let mut content = String::new();
file.read_to_string(&mut content).unwrap();
println!("fname: {}", &args[1]);
println!("lines: {}", lines(&content));
println!("chars: {}", chars(&content));
} else {
eprintln!("Could not load file!");
}
}
/******** 実行結果 ********
PS C:\Users\Darkn\cmd_input> cargo run test.txt
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
Running `target\debug\cmd_input.exe test.txt`
fname: test.txt
lines: 5
chars: 17
*************************/
実行結果は実行文を含んでいます。
エントリーポイントから解説します。
まずコマンドライン引数を受け取ります。ここで、もし引数が1つしかなければ、ファイル名を指定されていないので、パニックさせています。でなければ、指定されたファイルを開きます。
次に、ファイルが開けたかどうかを評価します。もしファイルが開けなければプログラムを終了します。
ファイルが開ければ内容を取得し、ユーザー定義関数「lines()」、「chars()」をそれぞれ実行して、文字列の行数および文字数(改行を除く)を取得しています。
おわりに
今回はコマンドライン引数について学びました。外部クレートを使う方法は後で編集して載せるかもしれません。
次回はファイルの読み書きを学びます。