サンプルプログラムの作成 2
コーディング解説
プログラム自体はとても簡単ですが、前回同様、各部の構成に分解して、それぞれ機能を解説します。
IDENTIFICATION DIVISION
前回、見出し部として説明した部分です。プログラム名は適宜指定してください。OpenCOBOLではソース格納ファイル名との整合性が取れていなくともエラーとはなりません。
000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. test-cob01.
ENVIRONMENT DIVISION
前回、環境部として説明した部分です。構成節の記述は省略します。今回は入出力節のみ記述し、入力ファイル1つと出力ファイル1つを定義しています。
000300 ENVIRONMENT DIVISION. 000400 INPUT-OUTPUT SECTION. 000500 FILE-CONTROL. 000600 SELECT I-FILE 000700 ASSIGN TO W-INPUT-FILENAME 000800 ORGANIZATION LINE SEQUENTIAL. 000900 SELECT O-FILE 001000 ASSIGN TO W-OUTPUT-FILENAME 001100 ORGANIZATION LINE SEQUENTIAL.
順序番号000600から000800までが入力ファイルの設定です。プログラム中では、I-FILEという識別で使用します。Linuxの実ファイル名はW-INPUT-FILENAME(DATA DIVISIONで定義)で示されます。順編成ファイルなので、ORGANIZATION LINE SEQUENTIALと指定しています。
順序番号000900から001100までが出力ファイルの設定です。内容は入力ファイルと同様です。
ここでは、ファイルの編成やファイル名などの物理情報を設定します。ファイル名は、W-INPUT-FILENAME等で間接指定していますが、直接ハードコーデングすることもできます。
000600 SELECT I-FILE 000700 ASSIGN TO "test.in" 000800 ORGANIZATION LINE SEQUENTIAL. 000900 SELECT O-FILE 001000 ASSIGN TO "test.out" 001100 ORGANIZATION LINE SEQUENTIAL.
コマンドラインからファイル名を指定することもできます。この方法については後述します。
DATA DIVISION
前回、データ部として説明した部分です。今回はファイル節と作業場所節を記述しています。
順序番号001400から001700が入力ファイルのレコード定義、001800から002100が出力ファイルのレコード定義です。いずれも1024バイトのエリアを定義していますが、1024バイトの固定長という意味でなく、入出力作業領域とでも理解しておいてください。
001200 DATA DIVISION. 001300 FILE SECTION. 001400 FD I-FILE 001500 LABEL RECORDS ARE STANDARD. 001600 01 INP-REC. 001700 03 PIC X(1024). 001800 FD O-FILE 001900 LABEL RECORDS ARE STANDARD. 002000 01 OUT-REC. 002100 03 PIC X(1024).
順序番号002200と002300は環境部で指定された入出力ファイルのファイル名を格納しています。今回はファイル名をプログラム内部にハードコーディングとしました。
順序番号002600は、入力ファイル終端判定用のスイッチとして利用します。
順序番号002700と002800は行番号として振る値の初期値と増分で利用します。
順序番号002900から003100は入力レコードを転記し、内容を書き換えるために用意した領域です。NUMBERINGに初期値と増分を利用した順序番号を更新して格納します。
002200 WORKING-STORAGE SECTION. 002300 77 W-INPUT-FILENAME PIC X(256) VALUE "test.in". 002400 77 W-OUTPUT-FILENAME PIC X(256) VALUE "test.out". 002600 77 W-EOF PIC X VALUE LOW-VALUE. 002700 77 W-COUNT PIC 9(6) VALUE 0. 002800 77 W-ADD PIC 9(6) VALUE 100. 002900 01 WORK-REC. 003000 03 NUMBERING PIC 9(6) VALUE 0. 003100 03 FILLER PIC X(1018).
PROCEDURE DIVISION
前回、手続き部として説明した部分です。
003300 PROCEDURE DIVISION. 003400 OPEN INPUT I-FILE. 003500 OPEN OUTPUT O-FILE. 003600 READ I-FILE INTO INP-REC AT END MOVE HIGH-VALUE TO W-EOF. 003700 PERFORM UNTIL W-EOF = HIGH-VALUE 003800 MOVE INP-REC TO WORK-REC 003900 ADD W-ADD TO W-COUNT 004000 MOVE W-COUNT TO NUMBERING OF WORK-REC 004100 WRITE OUT-REC FROM WORK-REC 004200 READ I-FILE INTO INP-REC 004300 AT END MOVE HIGH-VALUE TO W-EOF END-READ 004400 END-PERFORM. 004500 CLOSE I-FILE. 004600 CLOSE O-FILE. 004700 STOP RUN.
ファイルオープン
使用するファイルの準備をします。順序番号003400と003500の2行2文で記述していますが、1文で記述することも可能です。
003400 OPEN INPUT I-FILE OUTPUT O-FILE.
この文で、環境部とデータ部で定義したファイルを用途別にオープンします。ここでは、I-FILEを入力ファイルにO-FILEを出力ファイルとしてオープンしています。
先読み
データ処理の手法の一種です。コーディングを見ると分かりますが、同じ読み込み文が繰り返し処理の外側と内側にあります。一見、無駄なコーディングのように思われるかもしれませんが、データ構造が複数になり、ネストが深くなっても、この手法だと各繰り返し処理のコーディングが単純になり、間違いを減らすことができます。
順序番号003600が先読みのレコード、それに対応する繰り返し処理内側の読み込みが004200と004300です。
EOFまで繰り返し
繰り返しの条件は、ファイル終了までとしています。READ文では、ファイル終了を検知できるので、終了となったときに、順序番号002600で定義した入力ファイル終端判定用スイッチに値を入れます。スイッチの値としては、慣例では、ファイル終端検知前はLOW-VALUE(キャラクタベースで言う最小値)を格納しておき、ファイル終端検知時にHIGH-VALUE(キャラクタベースで言う最大値)を格納するようにしていることが多いです。
ファイルクローズ
処理終了後、プログラムを終了する前に必ずファイルをクローズします。順序番号004500と004600の2行2文で記述していますが、1文で記述することも可能です。
004500 CLOSE I-FILE O-FILE.
プログラム終了
プログラム終了し、上位処理に制御を渡す位置で、STOP RUN.文をコーディングしておきます。リターンコードを返したい場合は、STOP RUN.でプログラムが終了する前に、RETURN-CODEに値を設定しておきます。
コンパイル
今回のサンプルコードを用意しましたので適宜ご利用ください。サンプルコードを適当なディレクトリ、ファイルに格納してコンパイルをします。今回も、単一ソース、単純なプログラムですので、直接実行ファイルを出力する方法とします。
以下は、ソースファイル名をtest-cob01.cobとした場合の例です。
/usr/local/bin/cobc -x test-cob01.cob
コンパイル後に内容を確認してください。エラーがなければ同一のディレクトリに実行ファイル"test-cob01"が作成されているはずです。
実行
実行に先立ち入力ファイルを用意します。順序番号を成形する処理ですので、そのままサンプルコードを流用してもかまいません。
ただし、サンプルコードでは初期値0、増減値+100となっており、このまま実行しても、同じ結果となるので、順序番号部分を適宜変更すると、うまく確認できると思います。
[e-fuse@]$ cp test-cob01.cob test.in [e-fuse@]$
入力ファイルを準備しましたら早速実行してみてください。
[e-fuse@]$ ./test-cob01 [e-fuse@]$
もし、"error while loading shared..."と、エラーが出た場合は、適宜環境を整えて再度実行してください(→COBOL言語をLinux環境で動かす(4ページ))。
実行後、test.outが作られていると思いますので、内容を確認してみてください。
[e-fuse@]$ cat test.out 000100*COPYRIGHT(C)2008 FUSEKAKO allright reserved. 000200 IDENTIFICATION DIVISION. 000300 PROGRAM-ID. test-cob01. 000400 ENVIRONMENT DIVISION. 000500 INPUT-OUTPUT SECTION. ...(途中省略)... 004500 END-PERFORM. 004600 CLOSE I-FILE. 004700 CLOSE O-FILE. 004800 STOP RUN. [e-fuse@]$
上記のように、順序番号が成形されていることが確認できました。
