イメージとしてはC言語のstrlen関数みたいに引数に文字列変数を指定すれば文字列長(何文字あるか?)を返してくれる処理をWindowsバッチファイルでやろう!ということです。
サンプルプログラム
文字列長を求める部分はラベル機能を使って関数っぽく作りました。
REM ----- strlen関数もどき -----
:strlen
set length=0
set str=%1
:loop
if "%str%"=="" (goto :endloop)
set str=%str:~0,-1%
set /a length=%length%+1
goto :loop
:endloop
exit /b 0
関数っぽくといっても戻り値みたいなことはできないため、lengthという変数に文字列長を格納するようにしています。
set length=0
使い方も含めたサンプルを作りました。
strlen.bat
@echo off
REM ----------------------------
REM C言語のstrlenを再現する
REM ----------------------------
setlocal
set /p NAME="文字列をいれてね > "
call :strlen %NAME%
echo %NAME% は %length% 文字あるよ
exit /b 0
REM ----- strlen関数もどき -----
:strlen
set length=0
set str=%1
:loop
if "%str%"=="" (goto :endloop)
set str=%str:~0,-1%
set /a length=%length%+1
goto :loop
:endloop
exit /b 0
endlocal
実行イメージ
実行すると「文字列をいれてね > 」と聞いてくるので、適当に文字列を入れて下さい。
上記イメージでは、半角文字と全角文字にわけて2回実行していますが、きちんと文字列長が取得できています。(ちなみに半角と全角文字混在でも問題なく動きます)
バッチプログラムの解説
:strlen以下の文字列長を求める処理部分についてまずは解説します。
処理の流れを図示するとこのようになります。ポイントはループ中にある set命令 です。
先頭から順を追って解説します。
:strlen
呼び出すときのラベル名です。
バッチファイルでは、call :strlenとすれば:strlen以下の処理を呼び出すことができます。
set length=0
変数lengthに0を代入しています。
set str=%1
変数strにラベル:strlenを呼び出したときの引数に指定した値を代入しています。
例えばcall :strlen Helloとして呼び出すと「Hello」の値が%1にセットされることになり、最終的に変数strの値は、「Hello」となります。
:loop
if "%str%"=="" (goto :endloop)
set str=%str:~0,-1%
set /a length=%length%+1
goto :loop
:loop ~ goto :loop までは繰り返し処理となります。
このままでは無限ループになってしまいますので、:loop の下にif文があります。
if "%str%"=="" (goto :endloop)
変数strの文字列の中身が空になったら :endloop に処理を移動しなさい、という意味です。
set str=%str:~0,-1%
バッチファイルの変数には、展開という機能があり、変数内の指定範囲を取り出す機能があります。
記述方法)%変数名:~開始位置,終了位置%
例えば、変数strの先頭から2文字取り出すには、 %str:~0,2% と記述します。
終了位置に負の数を指定すると末尾から何文字までという意味になります。
よって、%str:~0,-1%の意味は、先頭から末尾の1文字手前までという意味になり、strの初期値が「Hello」だったとすればstrには「Hello」が代入されることになります。
要するにこれは変数内の文字列を1文字ずつ減らしていく処理ということです。
set /a length=%length%+1
setコマンドのオプション/aを指定すると変数の演算ができます。
変数lengthの値を1ずつ加算している処理です。(=のあとの計算式に変数名を使う場合は%で変数名をくくる必要があります)
:endloop
goto :loopからのループ処理を前述したif文で抜けるために最後に:endloopラベルを配置しています。
exit /b 0
ラベルで呼んだ処理の完了をあらわします。
exitコマンドの基本的な使い方はexit /bですが、後ろに数値をつけると終了コードをあらわします。特に0をつけなくても問題はありません。
通常exit /bとすればバッチファイル終了ですが、callで呼ばれたラベルの最後にexit /bがあるとcallで呼ばれた処理の次の処理に戻ります。
次にサンプルstrlen.batの全体処理について解説します。
@echo off
バッチファイル実行中にコマンドを表示させないための記述です。
これがないとコメント文の REM ——————- などもそのまま画面に表示されてしまいます。
setlocal ~ endlocal
は対になっています。
これをつけないとグローバル変数として定義されてしまいバッチファイル終了後も変数の中身が残ってしまいます。
set /p NAME="文字列をいれてね > "
setコマンドのオプション/pをつけるとキーボード入力が可能となります。
記述方法)set /p 変数名=”入力時の表示メッセージ“
変数NAMEにキーボードから入力した文字列を代入しています。
call :strlen %NAME%
:strlen以下を呼び出します。
その際、引数に%NAME%を指定しているためキーボードから入力した文字列が:strlen以下の%1に渡されます。
echo %NAME% は %length% 文字あるよ
exit /b 0
変数NAMEと:strlen以下で求めた変数lengthの値を表示してバッチ処理を終了します。
コメント