【PL/I学習|豆知識】PL/Iで文字列を賢く切り出す:SUBSTRの「長さ省略」テクニック

1. 導入:なぜ長さの省略が重要なのか

メインフレームのPL/I開発において、文字列処理は避けて通れません。特にファイルパスや可変長データ(VARYING)から特定のセパレータ以降を取り出す際、毎回「残り文字数」を計算するのは非効率的です。SUBSTR関数で「長さ」を省略する書き方は、コードを簡潔にするだけでなく、計算ミスによるバグを減らすために非常に重要なテクニックです。

2. 基礎知識:SUBSTR関数の仕組み

PL/IのSUBSTR(S, i, n)関数は、文字列Sのi番目からn文字分を切り出します。ここで重要なのは、第3引数の「n(長さ)」を省略できるという仕様です。
省略した場合、i番目から文字列の末尾までがすべて取得されます。
注意点として、PL/Iのインデックスは「1から始まる」という点です。JavaやC言語のような0始まりの言語に慣れていると、オフセット計算で「+1」を忘れるミスが多発するため、ここを意識することが設計の肝となります。

3. 実装と解決策

例えば、「ディレクトリ/ファイル名」という文字列からファイル名だけを抽出したい場合、INDEX関数とSUBSTR関数を組み合わせるのが定石です。INDEXで見つけた区切り文字の位置に「+1」をすることで、不要な区切り文字をスキップし、残りの文字列を安全に取得できます。

4. サンプルプログラム

以下は、VARYING属性の文字列から特定文字以降を抽出する実用的なコード例です。

/ サンプルコード:パスからファイル名を抽出する /
DCL FULL_PATH CHAR(100) VARYING INITIAL(‘USER/DATA/REPORT.TXT’);
DCL FILE_NAME CHAR(50) VARYING;
DCL POS FIXED BIN(15);

/ ‘/’ が最後に出現する位置を探す(簡易的な例としてINDEXを使用) /
POS = INDEX(FULL_PATH, ‘/’);

/
INDEXで見つかった位置の次(+1)から、
長さ引数を省略することで末尾までを自動的に取得する
/
IF POS > 0 THEN
FILE_NAME = SUBSTR(FULL_PATH, POS + 1);
ELSE
FILE_NAME = FULL_PATH;

/ 結果を表示(デバッグ用) /
PUT SKIP LIST(‘抽出されたファイル名: ‘ || FILE_NAME);

5. 応用・注意点

現場で陥りやすい最大のバグは、「オフセット計算での1文字ズレ」です。特に、区切り文字が文字列の最後に存在する場合、INDEXの結果と+1の計算がどうなるかを境界値テストで必ず確認してください。
また、VARYING変数を使用している場合、ターゲット変数の最大長(DECLARE時のサイズ)を超えてSUBSTR結果を代入しようとすると、実行時に文字列切捨て(Truncation)が発生し、エラーや意図しないデータ欠損を招くことがあります。代入先の変数は、常に十分なサイズを確保しておくことが肝要です。

コメント

タイトルとURLをコピーしました