■ 文字の結合(STRING文)
色々と事情があって、
COBOLで動的に文字列を生成しなければならなくなりました。
COBOLの場合、事前に変数のサイズまでキッチリと決めてしまうので、文字の編集をするのが中々に面倒です。
色々と方法はあるのですが、私はSTRING文を使う事が多いです。
...多い筈なのですが、
COBOLの新規作成って案件自体が少ないので、使う時にはすっかり忘れちゃって、過去に作ったソースファイルやマニュアルを見直す有様です。
毎回確認するのが面倒になったので、内容を整理して書き残すことにしました。
■ STRING文(サンプル)
下記は、定数、Xタイプ、9タイプを結合するサンプルになります。
WORKING-STORAGE SECTION.
01 WK-AREA.
03 WK-NUM PIC 9(2). *> テスト用数値
03 WK-STR PIC X(10). *> テスト用文字
03 WK-TXT PIC X(30). *> 結合先
*
PROCEDURE DIVISION.
*
* *> 数値に5、文字に"ABC"を設定
COMPUTE WK-NUM = 5.
MOVE "ABC" TO WK-STR.
*
* *> 結合した結果
STRING
"S-" DELIMITED BY SIZE
WK-NUM DELIMITED BY SIZE
"-" DELIMITED BY SIZE
WK-STR DELIMITED BY SIZE
"-E" DELIMITED BY SIZE
INTO WK-TXT
END-STRING.
*
* *> 結合した結果をコンソールに出力
DISPLAY "[" WK-TXT "]" UPON CONSOLE.
COBOLの良くある文法通りで、STRING で始まり END-STRING で終わります。
最後の INTO の後に、結合結果の出力先を指定します。
結合する情報の設定は、見ての通りですね。項目ごとに DELIMITED BY SIZE を付けていますが、これはお約束と思って良いかと。
実際には、SIZE の部分を工夫することで面白い事が出来ますが、面白テクニックの領域な上に、今一つ用途が無いので使ったことがありません。
■ STRING文(結果検証)
コンソールへの出力結果は、こうなります。
[S-05-ABC -E]
9タイプのWK-NUMには1桁の数値(5)を設定したのですが、2桁(05)になっています。どうやら、先頭の0を除くような動作はしないようです。まぁ、個人的にはそっちの方が都合が良いので、これはこれで良しと考えますか。
宣言通りのサイズで結合されるのはXタイプも同じで、事前に設定した文字は3桁(ABC)ですが、宣言した10桁で結合されています。
...うーん、数値(9タイプ)は良いのですが、文字(Xタイプ)の方が気に入りませんね。
■ STRING文(右側空白除去)
実の所、文字列の結合って何に使うのかって考えると、多くの場合は間に空白があっては都合が悪いと思うのですよ。
例えば、何らかのコマンドを発行する処理があったとして、そのコマンドのパラメータはダブルクォートで囲う必要がある。そして、そのパラメータに設定する値は常に変化するなんて場合ですかね。
そうすると「変数内で有効な文字数ってどこまでなのか」を判断してやる必要があるわけです。
WORKING-STORAGE SECTION.
01 WK-AREA.
03 WK-STR PIC X(10). *> テスト用文字
03 WK-TXT PIC X(30). *> 結合先
*
PROCEDURE DIVISION.
*
* *> 文字に"ABC"を設定
MOVE "ABC" TO WK-STR.
*
* *> 結合した結果
STRING
"testCMD " DELIMITED BY SIZE
"printer " DELIMITED BY SIZE
"""" DELIMITED BY SIZE
WK-STR(1:FUNCTION STORED-CHAR-LENGTH(WK-STR))
DELIMITED BY SIZE
"""" DELIMITED BY SIZE
INTO WK-TXT
END-STRING.
*
* *> 結合した結果をコンソールに出力
DISPLAY WK-TXT UPON CONSOLE.
Net
COBOLには、STORED-CHAR-LENGTH という便利な関数があって、末尾の空白を除いた長さを返してくれます。
この関数を利用して、変数 WK-STR の 1文字目から末尾の空白を除いた長さまでを部分参照してやります。
上でダブルクォートって書いたので、前後にダブルクォートも追加してみました。
コンソールには、このように出力されます。
testCMD printer "ABC"
■ 後書き
最後の右側空白の除去ですが、実際には別の方法もあるかと思います。
手っ取り早いのは、WK-STR(1:FUNCTION STORED-CHAR-LENGTH(WK-STR)) DELIMITED BY
SIZE を WK-STR DELIMITED BY
SPACE に書き換える事です。
DELIMITED BY なんたらは、なんたらの部分で指定した文字が現れるまでの部分を結合対象にするって意味になります。
なので、上記のサンプルの場合は SIZE → SPACE とすることでも結果は変わりません。ただし、文字列中にSPACEが複数あった場合には使えないので、あまりお勧め出来ないですね。
後、
COBOLはベンダーの独自拡張の色合いが強い言語なので、STORED-CHAR-LENGTH関数が使えない場合もあるかと思います。
その場合は、別の関数(あればですが)を使うか自作することになると思います(←既に他人ごとだと思ってます)。
投稿記事の一覧:
http://harikofu.web.fc2.com/--- blog end ---
スポンサードリンク