【COBOL学習|豆知識】COBOLの落とし穴:STRING文で「ゴミデータ」を残さないための作法

導入:なぜSTRING文の「残り」を意識すべきか

COBOL開発において、複数の文字列を結合する際に多用する「STRING文」。しかし、ベテランの現場でも意外と見落とされがちなのが、受取り側項目(送り出し先)の「結合されなかった領域」の扱いです。他の言語の文字列連結と異なり、COBOLのSTRING文は「指定した文字だけを上書き」します。その結果、元々入っていた古いデータが末尾に残ってしまうという「部分破壊」が発生します。これが原因で、後続の処理で予期せぬ不具合を招くケースが後を絶ちません。今回は、このリスクを回避し、安全にデータを扱うための定石を解説します。

基礎知識:STRING文の仕組み

STRING文は、複数の送り出し項目を連結して一つの受取り側項目に格納する命令です。ここで重要なのは、MOVE命令とは挙動が異なるという点です。MOVE命令は、値を転送する際に項目全体をクリアし、指定値以外は空白(SPACES)で埋めます。しかし、STRING文は「指定した文字を書き込むだけ」です。つまり、受取り側項目に既に値が入っている場合、連結した文字数分だけが上書きされ、それ以降の領域は「以前の値がそのまま残る」仕組みになっています。

実装・解決策:プロの定石

この問題を解決する最も確実な方法は、連結処理を実行する直前に受取り側項目を初期化することです。具体的には、INITIALIZE命令やMOVE SPACES命令を使用して、受取り側を空の状態にします。また、より細かな制御が必要な場合は、POINTER句を活用して、最後に書き込まれた位置を把握し、そこから末尾までをスペースで埋める方法もあります。

サンプルプログラム

以下のコードは、STRING文実行前に適切に初期化を行うことで、ゴミデータを残さない安全な実装例です。


IDENTIFICATION DIVISION.
PROGRAM-ID. STRING-EXAMPLE.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 STR-A PIC X(05) VALUE 'ABCDE'.
01 STR-B PIC X(05) VALUE '12345'.
01 RESULT-FIELD PIC X(20) VALUE 'PREVIOUS_DATA_REMAINS'.

PROCEDURE DIVISION.
MAIN-PROCEDURE.
> 1. まず受取り側を初期化する (これがプロの定石)
MOVE SPACES TO RESULT-FIELD.

> 2. 文字列を連結
STRING STR-A DELIMITED BY SIZE
'-' DELIMITED BY SIZE
STR-B DELIMITED BY SIZE
INTO RESULT-FIELD.

> 結果の確認
DISPLAY '結果: [' RESULT-FIELD ']'.

STOP RUN.

応用・注意点:現場で陥りやすいバグの回避策

現場でよくある失敗として、「以前のデータが何らかの理由でクリアされず、古い情報が混ざったまま出力される」という事象があります。特に、ループ処理の中でSTRING文を繰り返し使用する場合、初期化を忘れると、前のループのデータが後ろに引きずられてしまいます。

また、POINTER句を使用している場合は、そのポインタ変数の値が「文字数+1」を指していることを常に意識してください。もし、受取り側項目のサイズを超えて書き込もうとすると、ON OVERFLOW句で制御しない限り、処理が中断されたり意図しない挙動になる可能性があります。常に「受取り側のサイズ」と「連結後の文字数」の整合性をチェックする習慣をつけましょう。安全なコードは、こうした「当たり前の初期化」の積み重ねから生まれます。

コメント

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