cobol 知识点集锦
COBOL <wbr> <wbr>知识点集锦(上) COBOL数据类型
计息是银行的一项重要业务,包括日常代理客户收、付计算客户利息和年度计息等。目前,这些工作大多数是在IBM ES9000主机的SAFE应用系统平台上进行,该系统联机程序和联机计息程序是用IBM 370汇编语言实现的。为方便汇编语言读写,在VSAM文件存储的数据中,数据存放格式进行了特殊的定义。如日期存放采用X(3)型,01年03月15日,存入EBCD码为X‘010315’。在进行年度计息时,为了实现各种复杂的运算工作,一般采用COBOL语言来实现各种运算。而采用COBOL语言读取X(3)型数据时,读出的是字符型数据,不能直接进行运算,必须转换为COBOL数据类型的数据后才能进行相应处理。如刚才的X‘010315’,需要转换为内部十进制数据X‘0010315C’。本文介绍一种用COBOL语言实现字符型X(3)与内部十进制数据相互转换的方法。
由X(3)型转换为内部十进制
由于日期数据总是大于零,在COBOL语言的工作单元节定义变量DATE-FIRST后,再追加定义COBOL语言的最小数据单元X‘000C’,即十进制12。由于重定义DATE-CASE为DATE-CHANGE后,DATE-CHANGE是原日期数据的1000倍,于是要在过程部将DATE-CHANGE除以1000。
首先,在COBOL程序WORKING-STORAGE SECTION. 中定义如下内容:
WORKING-STORAGE SECTION.
01 DATE-CASE.
02 DATE-FIRST PIC X(3).
02 DATE-SIGN PIC 9(4) COMP VALUE 12.;定点二进制数
01 DATE-CHANGE REDEFINES DATE-CASE PIC 9(9) COMP-3. ;内部十进制数据
01 DATE-HEX PIC X(3). ; 转换前数据
01 DATE-DEC PIC S9(7)COMP-3 . ; 转换后数据
然后,在过程部PROCEDURE DEVISION.中加入如下语句:
PROCEDURE DEVISION.
MOVE DATE-HEX TO DATE-FIRST .
COMPUTE DATE-CHANGE = DATE-
CHANGE / 1000.
MOVE DATE-CHANGE TO DATE-DEC.
由内部十进制转换为X(3)型
在进行相反的转换时,要消除因COBOL语言数据类型标志“C”引起的原日期数据前多加的一个0,所以需要将转换数据乘以10,再取出前6位数据即可。
首先,在COBOL程序WORKING-STORAGE SECTION. 中定义如下内容:
WORKING-STORAGE SECTION.
01 WORK-DATE PIC S9(7) COMP-3.
01 AA REDEFINES WORK-DATE.
02 A1 PIC X(3).
02 A2 PIC X(1).
01 DATE-HEX PIC X(3). ;转换后数据
01 DATE-DEC PIC S9(7) COMP-3.
;转换前数据
然后,在过程部PROCEDURE DEVISION.中加入如下语句即可:
PROCEDURE DIVISION.
MOVE DATE-DEC TO WORK-DATE。
COMPUTE WORK-DATE=WORK-DATE*10.
MOVE A1 TO DATE-HEX .
COBOL <wbr> <wbr>知识点集锦(上) cobol语法
REDEFINES
可以用不同的变量描述同一内存。
01 PART_RECODE USAGE DISPLAY
03 PART-TYPE PICTURE...
03 PART_TYPE_A.
05 PART_NUMBER PICTURE...
05 PART_COST PICTURE...
03 PART_TYPE_B REDEFINES PART_TYPE_A.
05 UPC_CODE PICTURE...
03 PART_TYPE_C REDEFINES PART_TYPE_A.
05 ISBN PICTURE...
根据PART_TYPE决定用PART_TYPE_A还是PART_TYPE_B还是PART_TYPE_C。
规则:
PART_TYPE_B和PART_TYPE_C长度不能大于PART_TYPE_A。
数据项不能有VALUE。
01层不能用REDEFINES.
PART_TYPE_B和PART_TYPE_C中不能有OCCURS.
PICTURE
定义基本项目的具体长度,格式,数据类型。可以简写成PIC.
格式字符串最多30个字符,可以包含下列字符:
A 字母A-Z,a-z,空格
B 插入空格
P 标量字符,代表字段中不显示的小数点位置
S 代数符号,实际显示取决于项目的USAGE
V 小数点位置
X 任何字符
Z 抑制前头的0并转换成空字符
0 插入0
9 数字0~9
/ 插入/
, 插入,(逗号不能作为字符串的最后一位,最后时逗号是分隔符)
. 插入.
* 抑制前头的0并转换成*
+ 正值插入+,负值插入-
- 正值插入空格,负值插入-
$ 插入美元号
CR 正值插入两个空格,负值插入CR
DB 正值插入两个空格,负值插入DB
例子:
03 VAR PIC AAAAA. VAR变量长度为5个字符,不能有数字,等价于03 STATE PIC A(5)。
输入ASDFG ,显示ASDFG
03 VAR PIC XXXXX. VAR变量长度为5个任意字符。等价于03 FILLER PIC X(5)。
输入123AS , 显示123AS
03 VAR PIC 99/XXX/9999 长度11,输入05may2004,显示05/may/2004
03 VAR PIC 0ABXXX/9999 长度11,输入05may2004,显示05 may/2004
03 VAR PIC 9(3) 长度3,0~999之间。
03 VAR PIC 9(4)V99 长度6,0.00~9999.99之间。
03 VAR PIC S9(5)V99 长度7,-99999.99~99999.99之间。
03 VAR PIC 9(6)PPP 长度6,可以是1000,2000,...,999999000。输入1234,显示1000。
03 VAR PIC PPP999 长度3,0.000001~0.000999之间。输入123,显示0.000123。
03 VAR PIC ZZZ.99,输入100.50,显示100.50;输入-51.50,显示51.50;
输入0,显示.00.
03 VAR PIC $ZZZ.ZZ-,输入100.50,显示$100.50;输入-51.50,显示$51.50-;
输入0,显示
03 VAR PIC $***,***.99CR,输入1000,显示$**1000.00;输入-1000,显示$**1000.00CR;
输入0,显示$***,***.00;输入51.5,显示$***,*51.50
03 VAR PIC $$$,$$$.99,输入100.50,显示$100.50;输入-100.50,显示$100.50;
输入0.777,显示$.77;输入0,显示$.00
03 VAR PIC $.$$$,输入1.00,显示$.00;输入0.65,显示$.65;
输入0,显示$.00;
03 VAR PIC $--,输入17.7,显示$17;输入-17.7,显示$-17;
输入-5,显示$-5
03 VAR PIC $999.99+,输入100.50,显示$100.50+;输入-100.50,显示$100.50-;
03 VAR PIC 9(3)B9(3),输入55,显示000 055;输入1000.78,显示001 000;
03 FILLER PIC X(44),补上44个空位。
USAGE 表示基本或组数据的类型。有BINARY,COMPUTATIONAL(COMP),DISPLAY,INDEX,PACKED-DECIMAL.
JUSTIFIED
03 VAR1 PIC X(5) JUSTIFIED RIGHT.
03 VAR2 PIC X(5).
输入XYZ,VAR1显示的是" XYZ",VAR2显示的是"XYZ "。
BLANK WHEN ZERO
03 VAR PIC $999,999.99 BLANK WHEN ZERO.
当字段值为0,这个项目设置为全部空格。
VALUE
定义的时候就赋值。
03 VAR PIC X(5) VALUE "ABCDE".
01 VAR VALUE ALL SPACES.
03 VAR1 PIC XXX.
03 VAR2 PIC XX.
算术语句
COBOL中操作符执行顺序为:取正(+)、取负(-)最高级,指数操作(**)其次,乘(*)、除(/)再其次,加(+)、减(-)最后。
ROUNDED 舍入操作。
77 A PIC 9V9 VALUE 9.1.
77 B PIC 9.
ADD 0.5 TO A GIVING B ON SIZE ERROR GO TO PROC1.
ADD 0.5 TO A GIVING B ROUNDED ON SIZE ERROR GO TO PROC2.
END-ADD.
ON SIZE ERROR 是当语句出现错误时执行的。本例中第一句话执行没有错误,所以ON SIZE ERROR
不执行PROC1.第二句话,当0.5加上9.1得到9.6,因为有ROUNDED,所以执行舍入操作,得到10。而B只有1位数字,所以发生错误,执行ON SIZE ERROR操作,跳转执行PROC2。
CORRESPONDING(CORR) 数据项同名时编写多条语句。ADD和SUBSTRACT有此选项。
01 A.
03 B.
05 B1 PIC 999V99.
05 B1 PIC 999V99.
05 B1 PIC 999V99.
03 C.
05 B1 PIC 999V99.
05 B1 PIC 999V99.
05 B1 PIC 999V99.
则语句ADD CORR B TO C.相当于执行了下面3条语句。
ADD B1 OF B TO B1 OF C.
ADD B2 OF B TO B2 OF C.
ADD B3 OF B TO B3 OF C.
组项目不一定要格式相同。一个组项目中的内容在另一个组项目中可以没有,数据项顺序也无关紧要。只是严格按照数据项名称对应。
ADD A,B GIVING C. END-ADD. 将A,B相加放入C。
SUBTRACT A,B FROM C. END-SUBTRACT. 从C中减去A,B.
MULTIPLY A BY B GIVING C. END-MULTIPLY. 将A,B相乘放入C。
DIVIDE A INTO B GIVING C. END-DIVIDE. 将B除于A的结果放入C.
DIVIDE A BY B GIVING C. END-DIVIDE. 将A除于B的结果放入C.
DIVIDE A BY B GIVING C REMAINDER D. 将A除于B的商放入C,余数放入D.
D=A-B*C.
77 C PIC S99V9.
77 D PIC S99V9.
DIVIDE 3 INTO 7 GIVING C REMAINDER D.
C的值为2.3,D为0.1。(D=7-3*2.3)
COMPUTE
除了取余操作要用DIVIDE外,其他操作都可以用此语句。本语句求值一个算术表达式,并将结果存放在一个或几个变量中。
COMPUTE A ROUNDED,B = X*Y/(N+M)+Z. 将X*Y/(N+M)+Z的结果存放在B中,然后舍入后放入A中。
MOVE
MOVE A TO B.
也可以用CORR选项。
MOVE CORR A TO B.
ACCEPT
从键盘或其他输入设备读取数据。
ACCEPT A FROM DEV. 从DEV读取数据到A,也可以省略FROM DEV,表示从键盘读取。
ACCEPT A FROM DATE/DAY/DAY-OF-WEEK/TIME.读取日期,表示为6个字符,如990909(1999年9月9日)。
读取当前日期在年度(前2位)中为第几天(后3位),表示为6个字符,如1994年4月1日表示为94091。
读取当前星期几,表示为1位字符。1表示星期一,7表示星期日。
读取当前时间,表示为8位字符。精确到毫秒。如下午2:41表示为14410000。
DISPLAY
将数据写入输出设备。如监视器(monite),系统输出流和操作员控制台(console)。
DISPLAY AAAAA BBBBB [UPON DEV] [WITH NO ADVANCING]
如果使用UPON选项,dev要与special-names段中的硬件名相关联。
如果使用no advancing选项,则输出最后一个字符后输出设备仍然保持原位,使下一条display语句还在该位置显示。否则可能到下一行显示。
INITIALIZE
初始化数据,数字和数字编辑数据项初始化为0,其他初始化为空格。
INSPECT TALLYING
计算项目中该字符串出现的次数。
INSPECT AA TALLYING BB FOR ALL “EE”. 从AA中查找有多少个EE,将个数写入BB。
INSPECT AA TALLYING BB FOR CHARACTERS BEFORE “E”. 从AA中查找E前面有多少个字符,将个数写入BB。
INSPECT AA TALLYING BB FOR CHARACTERS AFTER “C” BEFORE “E”. 从AA中查找C后面E前面有多少个字符,将个数写入BB。
INSPECT AA TALLYING BB FOR LEADING “E”. 从AA中第一个字符开始查找有多少个E,如果没有就结束操作,有就将个数写入BB,直至没有。
INSPECT AA TALLYING BB FOR LEADING “E” AFTER “C”. 从AA中C后面开始查找有多少个E,如果没有就结束操作,有就将个数写入BB,直至没有。
组合例子:
77 CS PIC X(9) VALUE "REELWHEEL".
77 COUNT-0.
77 COUNT-1.
77 COUNT-2.
MOVE 0 TO COUNT-0,COUNT-1,COUNT-2.
INSPECT CS TALLYING
COUNT-0 FOR ALL "E",
COUNT-1 FOR LEADING "W" AFTER "L",
COUNT-2 FOR CHARACTERS.
程序首先判断的是字符"R",执行COUNT-0 FOR ALL "E",因为第一个字符不是"E",所以程序转而执行COUNT-1 FOR LEADING "W" AFTER "L",也不符合要求,
于是程序执行COUNT-2 FOR CHARACTERS,COUNT-2 =1。然后字符串往下一位,判断"E",执行COUNT-0 FOR ALL "E",符合要求,则COUNT-0=1。
有了满足条件的判断,则余下的判断不再执行,字符串再往下一位,判断"E",则COUNT-0=2。接着判断"L",则COUNT-2 =2。以此类推,最后结果为COUNT-0=4,
COUNT-1=1,COUNT-2=4。
INSPECT REPLACING
用另一个字符串替换这个字符串。
还用上面的例子。
INSPECT CS REPLACING ALL "E" BY "Y". 结果"RYYLWHYYL"
INSPECT CS REPLACING CHARACTERS BY "Z" AFTER "L". 结果"REELZZZZZ"
INSPECT CS REPLACING LEADING "E" BY "Y". 结果不变
INSPECT CS REPLACING LEADING "E" BY "Z" AFTER "H". 结果"REELWHZZL"
INSPECT CS REPLACING FIRST "E" BY "I". 结果"RIELWHEEL"
INSPECT CS REPLACING FIRST "EE" BY "00",ALL "WH" BY "TH",CHARACTERS BY SPACE. 结果" 00 TH "
INSPECT CONVERTING
就是INSPECT REPLACING的缩写。
INSPECT CS CONVERTING "EE" TO "00". 也可以加上BEFORE,AFTER。
STRING
将几个字符串合并成一个字符串。
STRING A DELIMITED BY SPACE," !" DELIMITED BY SIZE INTO C.假设A中的内容是"HELLO",则结果是"HELLO !".
DELIMITED BY SPACE意思是碰到空格,或到A的结尾或C的结尾,则合并A字符串结束。
DELIMITED BY SIZE意思是到" !"的结尾或C的结尾,则合并" !"字符串结束。
STRING A INTO B POINTER C ON OVERFLOW PROC1 NOT ON OVERFLOW PROC2.
将A字符串复制到B中由C开始的地址处。如果C小于1或大于B的长度,或A的长度大于B中C到结尾处的长度,则发生
OVERFLOW溢出,执行PROC1。
UNSTRING
将一个字符串中的字符按照要求放入多个变量中。
UNSTRING AAA [DELIMITED BY [ALL] B [OR [ALL] C] ...] INTO { C [DELIMITER IN D] [COUNT IN E] } ...[WITH POINTER F] [TALLYING IN G] [ON OVERFLOW PROC1] [NOT ON OVERFLOW PROC2] [END-UNSTRING]
将AAA中的字符放入C,如果还有其他变量,如C2,则等C放满后放入C2。
DELIMITED BY和STRING中的作用一样。表示将AAA中到B为止的字符取出。如果有OR,则表示到B或C字符为止的字符取出。如果有ALL,则如果几个相同的B在一起,则认为是一个B。
DELIMITER IN 将B放入D,知道是哪个字符为分隔符。
COUNT IN 实际复制到C中的字符数放入E中。
WITH POINTER 和STRIGN中一样。
TALLYING IN 计算有几个接受项。访问一个新的接受项,G值加1。
例子:
03 CITY PIC X(10).
O3 ZIP PIC X(10).
77 TEST PIC X(20).
MOVE "NEW YORK,NY 10017" TO TEST.
UNSTRING TEST DELIMITED BY "," INTO CITY,ZIP.
执行结果CITY值是NEW YORK.ZIP的值是NY 10017。
逻辑和控制语句
IF (A [NOT] > B) 等价于 IF (A [NOT] GREATER THAN B)
IF (A [NOT] < B) 等价于 IF (A [NOT] LESS THAN B)
IF (A [NOT] = B) 等价于 IF (A [NOT] EQUAL TO B)
IF (A >= B) 等价于 IF (A GREATER THAN OR EQUAL TO B)
IF (A <= B) 等价于 IF (A LESS THAN OR EQUAL TO B)
IF (A [NOT] > B AND C) 表示A [NOT] 大于B 而且 A [NOT] 大于C
IF A IS [NOT] NUMERIC 数字和可选符号
IF A IS [NOT] ALPHABETIC A~Z,a~z字符和空格
IF A IS [NOT] ALPHABETIC-LOWER a~z字符和空格
IF A IS [NOT] ALPHABETIC-UPPER A~Z字符和空格
IF A IS [NOT] CLASS-NAME SPECIAL-NAMES定义的字符集
例如:SPECIAL-NAMES.
CLASS MYDEFINE IS "12345+ABCDE-".
判断变量是否定义了数值。这个变量是88层的,且要与一个数据项关联。
03 STATE PIC XX.
88 CON VALUES ARE "A","B","C".
IF CON ...
判断厂家定义运行开关的开/关状态。
SPECIAL-NAMES.
SWITCH-A ON STATUS IS A-ON ,OFF STATUS IS A-OFF.
IF A-ON...
若开关在开位置,则IF A-ON返回TRUE。
IF A IS [NOT] POSITIVE 判断是否大于0
IF A IS [NOT] NEGATIVE 判断是否小于0
IF A IS [NOT] ZERO 判断是否等于0
COBOL支持NOT ,AND ,OR 操作。
PERFORM
过程调用,但是不传递参数。
PERFORM PROC1 [THROUGH PROC2]
执行完PROC1再执行PROC2.没有THROUGH(THRU)就只执行PROC1.
PERFORM PROC1 [THRU PROC2] N TIMES
执行PROC1[或者还有PROC2]N次。
PERFORM PROC1 [THRU PROC2] [WITH TEST BEFORE/AFTER] UNTIL A NOT EUQAL 0.
执行PROC1[或者还有PROC2]直到A不等于0。WITH TEST BEFORE/AFTER指定在第一次执行之前还是之后判断条件。默认是BEFORE,执行之前判断。
PERFORM PROC1 [THRU PROC2] [WITH TEST BEFORE/AFTER] VARYING A FROM B BY C UNTIL CONDITION1 [AFTER D FROM E BY F UNTIL CONDITION2].
相当于FOR循环,将A的值从B开始,以C为单位递增,直到满足CONDITION1。AFTER语句是一个嵌套的FOR 循环。VARYING是外循环,AFTER是内循环。A,B可以是索引。
过程也可以直接写入PERFORM中。但是THROUGH就不好用了。语法如下 :
PERFORM 过程语句 END-PERFORM.
PERFORM N TIMES 过程语句 END-PERFORM.
PERFORM [WITH TEST BEFORE/AFTER] UNTIL CONDITION 过程语句 END-PERFORM.
PERFORM [WITH TEST BEFORE/AFTER] VARYING A FROM B BY C UNTIL CONDITION1 过程语句 END-PERFORM.
IF语句
IF CONDITION THEN STATEMENTS1/NEXT SENTENCE ELSE STATEMENTS2 END-IF/NEXT SENTENCE/ENDIF
NEXT SENTENCE将跳出IF操作语句执行下一条语句。
IF语句中不要使用.句号。.句号将结束所有IF语句。要结束一个嵌套的IF语句,可以使用END-IF或者NEXT SENTENCE.如
IF A IF B END-IF ELSE C END-IF.或者
IF A IF B ELSE NEXT SENTENCE ELSE C END-IF.
EVALUATE
相当于SWITCH CASE语句。
EVALUATE A
WHEN B ...
WHEN 0 THRU 100 ...(FROM 0 TO 100)
WHEN OTHER ...
[END-EVALUATE]
首先得到A的结果,和WHEN语句的参数比较,如果和B相等,就执行B后的操作,执行完了不再执行后面的WHEN语句。如果不等就执行下一条WHEN语句。如果没有相等的就执行WHEN OTHER语句。
EVALUATE A ALSO B
WHEN C ALSO D ...
WHEN E ALSO F ...
WHEN OTHER ...
对于有多个判断条件的,要多个条件同时满足。如上要C=A同时D=B,才执行WHEN语句。
CONTINUE
继续执行下面的程序。
GO TO
GO TO PROC1 [DEPENDING ON N] DEPENDING ON N将跳转到清单中的第N个PROC.
EXIT
一般为最后一句话。
STOP
STOP RUN 结束程序。
ALTER
ALTER PROC1 TO PROC2. 不懂什么意思,反正已经从标准中废除了这个语句。
ENTER
使其他编程语言中的语句可以放进当前源程序中。
ENTER LANGUAGE-NAME [ROUTINE-NAME]
LANGUAGE 是厂家指定可以输入COBOL的任何语言,这个语句后面是其他编程语言的语句,然后要用ENTERCOBOL表示返回COBOL语言。
如果无法将其他语言的程序直接放入,可以用ROUTINE-NAME引用其他语言编写的程序。
COBOL <wbr> <wbr>知识点集锦(上) cobol程序格式
cobol源程序的格式如下:
每行开头有6个字符的序号区。可以输入000010,000020等表示行,也可以不输。
序号区后面是一个字符(第7位)的指示符区,如第一行所示。可以用*和/表示注释,_表示续行,D表示调试。
指示符区后面是4个字符(8~11位)的A区。可以放入部,节,段标题,段名,层指示符和层号01与77,
关键字DECLARATIVES和END DECLARATIVES,程序结束标题。
A区后面(12位以后)是语句体,称为B区。过程部的语句必须从B区开始。B区宽度通常为72或80个字符。
本例是70个字符。
空行的每个区都是空格
标识部(2~4行),PROGRAM-ID段包含程序名,是每个程序都必须的。AUTHOR等其他段是可有可无的。
环境部(5~15行),提供与程序外部有关的项目,具体地说,就是列出程序所用的文件。如果不需要可以省略。
环境部有配置节(6~10行)和输入输出节(11~15行)。
第7行表示编译程序的计算机。如果指定WITH DEBUGGING MODE就编译调试行。
第8行表示程序运行的计算机。
第9,10行包含一组指定输出样式。这里是标准输出,可以自定义。
输入输出节只用于文件。
第13到15行表示如果程序使用文件,则这个段对每个文件包含一个项目。
文件控制项目的格式取决于文件的描述类型。
数据部(16~22行),提供程序变量的存放位置,对不同的数据类型分成不同的节:文件数据(File Section)、静态数据(Working-Storage Section)、参数(Linkage Section)、通信(Communication Section)、报表(Report Section)。
文件节(18~21行),每个文件描述中包含文件所含纪录的定义,文件节中的数据或从文件读取,
或由写文件的程序产生。
第22行表示工作存储节,这节包含程序所需的临时结果和初始化静态数据的数据。
参数(Linkage Section)包含调用程序传递的数据(其他语言中称为参数)。
通信(Communication Section),处理COBOL程序和通信设备之间的消息。
报表(Report Section),报表节实现COBOL报告编写工具系统所需的数据。
第20,21行的PIC是PICTURE的缩写,表示定义数据格式。
X(12)表示12个字符的字符串,9(09)表示9位的整数。
可以将基本项目组成层次结构,称为组数据项或组。
COBOL程序中的数据项的定义从层号开始,01层是最高层,49层是最低层。
77层项目用于某个组的数据项,如程序中的临时变量。
66层是为特殊描述符项目保留的,可以更名现有的数据项或组,或以原定义未允许的方式组合。
88层是对特殊数据项目条件名保留的
如:
03 STATE PIC XX.
88 NEW-ENGLAND VALUES ARE "1","2","3","4","5".
IF NEW-ENGLAND ... then do something
过程部(23~30行),包含构成程序的过程性语句。
带DECLARATIVES的过程部。有些程序用特殊的USE语句表示遇到特殊条件时要执行的过程,
如发生I/O错误时。
USE语句组合在一起,放在过程部开头,由关键字DECLARATIVES和END DECLARATIVES限定。
第24行相当于定义了一个名字叫ACAB030100-PROC()的函数。
第25,29行定义了标志,可以用GO TO 语句跳转到这个地方,执行下面的语句。
第26行在屏幕上打印,相当于printf("ACAB030100-START");
第27行是调用ACAB030100-PROC()函数。
cobol程序的要求:必须以英文句号.结束部标题、节标题、段名、项目和语句。
句号为小数点时,两边都要有数字。
COBOL <wbr> <wbr>知识点集锦(上) cobol文件操作
要在COBOL中使用文件,要在3个不同的部中放上信息。
环境部,要有程序使用的每个文件的文件控制项目(FILE-CONTROL)。这个项目将程序中使用的文件名与程序外的实际文件联系起来。这些项目还定义文件的组织和访问方式。
数据部,要有每个文件的文件描述符(FD)项目,就是数据定义。
过程部,放上处理语句,OPEN,READ,WRITE,DELETE等。
环境部中主要是FILE-CONTROL和I-O-CONTROL.I-O-CONTROL很少使用。
SELECT [OPTIONAL] file-name ASSIGN TO DEV/FILE
[RESERVE N [AREA/AREAS]]
[FILE STATUS IS VAR]
SELECT必须是第一句,其他顺序无关。file-name是程序中传递使用的文件名,相当于实际文件的一个别名。OPTIONAL用于执行可能不存在的文件。
ASSIGN将file-name连接到实际的外部设备或文件。(TO好像可以省略。)
RESERVE指定文件缓冲区。
FILE STATUS指定一个变量存放文件状态,这个变量应该已在WORKING-STORAGE SECTION中定义。
对于顺序文件,还有声明如下:
[ORGANIZATION IS SEQUENTIAL] 可选,缺省为顺序组织文件
[ACCESS MODE IS SEQUENTIAL] 可选。顺序文件只允许顺序访问
[PADDING CHARACTER IS char] 指定文件在固定块长设备上时键块所用的字符,char为一个字符的数据项。
[RECORD DELIMITER IS STANDARD/usr-define] 指定如何确定变长纪录的长度。
顺序文件例子:
SELECT file-name ASSIGN TO "/usr/file1"
FILE STATUS IS file-status
对于相对文件,还有声明如下:
[ORGANIZATION IS RELATIVE] 是相对文件必须的
[ACCESS MODE IS SEQUENTIAL [RELATIVE KEY IS data]] 或者
[ACCESS MODE IS RANDOM/DYNAMIC RELATIVE KEY IS data]
访问方式有3种,缺省是SEQUENTIAL。
RELATIVE KEY 可选。如果存在,则文件读取操作顺利完成后,data用所读取纪录的关键字更新。data应为文件的纪录区中没有的整数数据项。
相对文件的例子:
SELECT file-name ASSIGN TO "/usr/file2"
ORGANIZATION IS RELATIVE
ACCESS MODE IS DYNAMIC RELATIVE KEY IS DAY-NUMBER
FILE STATUS IS file-status
对于索引文件,还有声明如下:
[ORGANIZATION IS INDEXED] 是索引文件必须的
[ACCESS MODE IS SEQUENTIAL/RANDOM/DYNAMIC] RECORD KEY IS data1
[ALTERNATE RECORD KEY IS data2 [WITH DUPLICATES]]
访问方式有3种,缺省是SEQUENTIAL。
RECORD KEY 指定文件的主纪录关键字,data1应为定义该文件的某个记录区的字母数字数据项目。这个关键字的描述及其在数据记录中的位置应该与生成文件时所用的关键字一致。
ALTERNATE RECORD KEY 如果文件有替换关键字,则其关键字用这个从句的短语指定,索引中允许重复关键字时采用DUPLICATES.COBOL要求文件记录中定义data2。重复关键字的长度及其在数据记录中的位置应该与生成文件时一致,所有替换关键字应放在文件控制项中。
索引文件的例子:
SELECT file-name ASSIGN TO "/usr/file3"
ORGANIZATION IS INDEXED
ACCESS MODE IS RANDOM
RECORD KEY IS NUMBER OF EMPLOYEE-RECORD
ALTERNATE RECORD KEY IS LAST-NAME OF EMPLOYEE-RECORD WITH DUPLICATES
ALTERNATE RECORD KEY IS SS-NUMBER OF EMPLOYEE-RECORD
FILE STATUS IS file-status
这里用户在程序中使用的文件名是file-name,实际文件名是file3。file-name的定义放在程序后边的数据部的文件节中。文件是索引文件,程序可以随机访问文件。文件的主关键字是NUMBER OF EMPLOYEE-RECORD,替换关键字是LAST-NAME和SS-NUMBER,都是文件记录区的字段。LAST-NAME允许重复。
文件状态:(对文件操作时返回文件状态到定义的文件状态变量)
ANY 00 成功
ANY 02 对索引文件,成功但发现重复关键字
READ 04 成功,但纪录长度不符合指定长度
OPEN 05 成功,但文件是可选的,前面不存在
OPEN,CLOSE 07 对顺序文件,成功,但媒介不是盘
READ 10 文件已到末尾
READ 14 对相对文件,相对纪录号的有效位超过相对关键字数据项允许的位
WRITE,REWRITE 21 对索引文件,顺序出错
WRITE 22 对索引和相对文件,带这个关键字的纪录已经存在
START,READ 23 对索引和相对文件,带这个关键字的纪录不存在
WRITE 24 对相对文件,相对纪录号的有效位超过相对关键字数据项允许的位
ANY 30 I/O错误
WRITE 34 对顺序文件,发生超边界错误
OPEN 35 对顺序和相对文件,未发现非可选文件
OPEN 37 对顺序和相对文件,该文件不支持指定的打开方式
OPEN 38 对顺序和相对文件,文件已经用锁关闭
OPEN 39 对顺序和相对文件,文件属性不支持程序中指定的属性
OPEN 41 文件已经打开
CLOSE 42 文件未打开
DELETE,REWRITE 43 最近的操作不是READ
WRITE,REWRITE 44 纪录长度非法
READ 46 没有有效的下一个记录
READ,START 47 文件未在INPUT或I-O方式中打开
WRITE 48 文件未在OUTPUT或EXTEND方式中打开
DELETE,REWRITE 49 文件未在I-O方式中打开
ANY 90~99 厂家定义
由上可知,文件操作时会发生错误,COBOL提供了检查错误和恢复I/O错误的公用地点。过程部开头应包括DECLARATIVES部分,放上出现错误时要执行的语句。
PROCEDURE DIVISION.
DECLARATIVES.
section-name SECTION.
USE statement(出现错误时调用的节).
paragraph-name.
sentence...
END DECLARATIVES.
section-name SECTION.
paragraph-name.
sentence...
USE AFTER STANDARD EXCEPTION/ERROR PROCEDURE ON file-name/INPUT/OUTPUT/I-O/EXTEND
只能在USE语句中指定一个文件,一种方式也只能有一个USE语句。如果既指定了文件,也指定了方式,则文件优先。
程序使用的所有文件要定义在数据部的第一节----文件节中。
FD file-name
[BLOCK CONTAINS int-1 [TO int-2] RECORDS/CHARACTERS]
[RECORD (CONTAINS int-3 [TO int-4] CHARACTERS)/(IS VARYING IN SIZE [FROM int-5] [TO int-6] CHARACTERS)/(DEPENDING ON data1)
[LABEL (RECORD IS)/(RECORDS ARE) STANDARD/OMITTED]
[VALUE OF (implementor-name IS id-lit-1)...]
[DATA (RECORD IS)/(RECORDS ARE) data2]
BLOCK CONTAINS 指定实际纪录的具体长度或最大与最小长度的逻辑记录数或块数。一般有操作系统和文件系统指定。
RECORD 指定包含变长纪录的文件中记录的最大与最小长度或定长纪录的具体长度。
RECORD CONTAINS 如果不带TO,则int-3是每个纪录的长度;如果带TO,介于int-3和int-4之间。
RECORD IS VARYING 指定纪录长度最小int-5和最大int-6。
DEPENDING ON 如要用,则需要在data1中保存纪录长度。
LABEL RECORD 指定文件是否带标号。(过时,下个版本不包含)
VALUE 和LABEL一起检查标号的不同部分。(过时,下个版本不包含)
DATA RECORD 指定属于文件的纪录描述项(FD后的01层项目)并作为程序文档。(过时,下个版本不包含)
一般定义文件只用第一句:FD file-name
顺序文件的LINAGE声明
对顺序文件,LINAGE声明可以在文件输出是打印机或打印机兼容文件时指定一些打印细节。
[LINAGE IS BODY LINES [WITH FOOTING AT FOOT][LINES AT TOP TOP][LINES AT BOTTOM BOTTOM]] [CODE-SET IS alphabet-name]
整个文件分成TOP,BODY,BOTTOM三部分。其中BODY包含有FOOT.
CODE-SET指定文件中所用的字符集。
过程部主要是对文件的OPEN,CLOSE,READ,WRITE,START,REWRITE,DELETE等操作。
OPEN
OPEN文件有4种方式:(如果文件声明为OPTIONAL,则文件不存在会创建文件,否则会报错)
OPEN INPUT FILE-NAME. 只能读取的文件。
OPEN OUTPUT FILE-NAME. 生成写入纪录的文件,读取该文件会出错。若文件已存在,已有记录会被全部删除。
OPEN I-O FILE-NAME. 可读可写的文件。
OPEN EXTEND FILE-NAME. 生成写入的文件。与UOTPUT的区别在于,若文件已存在,EXTEND将纪录加在文件末尾。
如果OPEN不成功,执行USE语句。USE语句不存在,则程序结束。
顺序文件的OPEN可以有以下方式:
OPEN INPUT FILE-NAME [(WITH NO REWIND)/REVERSED].
OPEN OUTPUT FILE-NAME [WITH NO REWIND].
REVERSED可以逆序处理,即由后向前处理。(过时,下个版本不包含)
WITH NO REWIND 用于单卷磁带文件,如果指定文件在不适用REWIND的媒介上,忽略。
在文件描述项中指定LINAGE得顺序文件不能用EXTEND方式打开。
CLOSE
所有文件的CLOSE方法:
CLOSE FILE-NAME. 关闭文件。
CLOSE FILE-NAME WITH LOCK. 关闭文件,不退出程序不能再打开此文件。
顺序文件还有其他一些选项,如关闭卷或单元,和继续处理文件:
CLOSE file-name [REEL/UNIT] [FOR REMOVAL]/WITH NO REWIND
READ
顺序访问方式读文件。一定要有NEXT字样。
READ file-name [NEXT] RECORD [INTO data1]
[AT END statements][NOT AT END statements] [END-READ]
如果READ成功且有INTO,将读到的数据写入data1。
如果文件中没有记录,执行AT ENDstatements,如果没有就执行USE。
如果READ成功,就执行NOT AT END statements。
动态访问方式读文件。(相对或索引文件)
利用OPEN语句,将文件指针设在开头。
进行各种成功的READ操作。
有START语句标识文件中的纪录。
随机访问方式读文件。
READ file-name RECORD [INTO data1]
[INVALID KEY statements][NOT INVALID KEY statements] [END-READ]
如果READ成功且有INTO,将读到的数据写入data1。
如果文件中没有记录,执行INVALID KEY statements,如果没有就执行USE。
如果READ成功,就执行NOT INVALID KEY statements。
如果是相对文件,要设置文件控制项RELATIVE KEY中指定的整型关键字值后才能执行READ.
如果是索引文件,要设置当前索引的关键字值后才能执行READ.
WRITE
顺序方式。
WRITE data [FROM data1] [BEFORE/AFTER ADVANCING mnemonic-name/PAGE/N LINE(LINES)]
[AT END-OF-PAGE(EOP) statements][NOT AT END-OF-PAGE(EOP) statements][END-WRITE]
如果指定了FROM,先将data1复制到data,再写入文件。
BEFORE/AFTER ADVANCING N LINE(LINES) 在纪录间插入N个空行。
AT END-OF-PAGE(EOP) 对于带LINAGE的文件有效,在WRITE使指针进入页脚(FOOT)时,先执行WRITE,再执行AT END-OF-PAGE(EOP) statements。
相对和索引文件方式。
WRITE data [FROM data1]
[INVALID KEY statements][NOT INVALID KEY statements] [END-WRITE]
REWRITE
替换文件中的一个记录。
顺序方式:REWRITE data [FROM data1] [END-REWRITE]
相对和索引方式:
REWRITE data [FROM data1]
[INVALID KEY statements][NOT INVALID KEY statements] [END-REWRITE]
DELETE
删除文件中的一个记录。只能用于相对或索引组织的文件。
DELETE file-name RECORD
[INVALID KEY statements][NOT INVALID KEY statements] [END-DELETE]
顺序访问方式的话,前一个READ的纪录被删除。
随机或动态访问的话,RELATIVE KEY的内容或主关键字所表示的纪录从文件中删除。
START
将相对或索引文件定位到某个纪录,以便对其进行顺序访问。只对相对和索引文件有效。
START file-name [KEY IS (EQUAL TO)/=/GREATER THAN/>/NOT LESS THAN/NOT < data]
[INVALID KEY statements][NOT INVALID KEY statements] [END-START]
如果执行成功,则data所属的索引变成文件的当前索引。
对于相对文件,data定义为文件的RELATIVE KEY的数据项。
对于索引文件,data为下列之一:
文件的主关键字,是RECORD KEY从句中指定的数据项。
文件的替换关键字,是ALTERNATE RECORD KEY从句指定的数据项。
从一个关键字的第一个位置开头,长度小于或等于该关键字的数据项。
COBOL <wbr> <wbr>知识点集锦(上) cobol数组操作
下面是数组的例子:
01 RECORD-X.
03 MONTH OCCURS 12 TIMES.
05 NAME PIC X(12).
05 DAYS OCCURS 31 TIEMS.
07 COMMENT PIC X(20).
07 TEMP-HI PIC S999.
07 TEMP-LO PIC S999.
77 CURRENT-DAY PIC 99.
调用表示如下:
MONTH(5) : 包含NAME 和 DAYS表格的组项目。
NAME OF MONTH(5) :基本字母数字项目,长度为12个字符。
NAME(5) (1:3) 上述第5个项目的前3个字符。
TEMP-HI(1,31) 基本数字项目,长度为3个字符。前一个参数是在MONTH数组中的位置,后一个参数是在DAYS数组中的位置。相当于MONTH[1].DAYS[31].TEMP-HI。
COMMENT OF RECORD-X(5,CURRENT-DAY)(11) 基本字母数字项目第五个月的CURRENT-DAY的COMMENT字段的最后10个字符。
03 TEXT PIC XXX OCCURS 1 TO 12 TIMES DEPENDING ON IX.
定义一个变长的数组。定义的长度是12,实际以IX为准,若IX为10,则TEXT的长度就是30。
索引
索引名INDEX
索引名可以用作PERFORM语句的变量,用于SET和SEARCH语句和用作下标。
03 TEXT PIC XXX OCCURS 7 TIMES INDEXED BY index
05 A PIC XXX
05 B PIC XXX
PERFORM VARYING index FROM 1 BY 1 UNTIL index >7
DISPLAY A(index),B(index)
END-PERFORM.
注意和不用索引名的比较:
77 index PIC 99
03 TEXT PIC XXX OCCURS 7 TIMES
05 A PIC XXX
05 B PIC XXX
PERFORM VARYING index FROM 1 BY 1 UNTIL index >7
DISPLAY A(index),B(index)
END-PERFORM.
关键字KEY
关键字有ASCENDING(升序,由低到高)和DESCENDING(降序,由高到低)。
03 TEXT PIC XXX OCCURS 7 TIMES ASCENDING KEY IS A,B.
05 A PIC XXX.
05 B PIC XXX.
TEXT中的元素按A升序排序,A相同的元素按B升序排序。
关键字的作用是定义SEARCH语句带ALL短语时表格的排序。
表格初始化,可以一个一个数据项单独初始化,也可以一起初始化。
03 TEXT PIC XXX OCCURS 7 TIMES VALUES SPACE.
05 A PIC XXX.
05 B PIC XXX. 一起初始化为空格。
03 TEXT PIC XXX OCCURS 7 TIMES.
05 A PIC XXX VALUES SPACE.
05 B PIC XXX VALUES SPACE. 单独初始化。
SET
保存或恢复索引值。SET A TO B.
将索引递增或递减一个整数值。SET A UP/DOWN BY N.
SEARCH
SEARCH A [VARYING B] AT END C {WHEN CONDITION D}...END-SEARCH
A为带INDEXED BY 短语的表格。每一步都轮流求值CONDITION ,为真时执行D,SEARCH语句终止。 为假时,索引值递增,至最大索引时执行AT END C,SEARCH语句终止。
若一开始索引值即为最大,则不执行WHEN语句,直接执行AT END 语句。
VARYING 指定索引B,省略为A中制定的索引。
下面的例子查找月份表中下一个具有31天的月份。
01 MONTH-DATA.
03 MONTH-INFO.
05 PIC X(10) VALUES "JANUARY".
05 PIC X(3) VALUES "JAN".
05 PIC 99 VALUES 31.
05 PIC X(10) VALUES "FEBRUARY".
05 PIC X(3) VALUES "FEB".
05 PIC 99 VALUES 28.
...(省略代码)
03 MONTH REDEFINES MONTH-INFO OCCURS 12 TIMES INDEXED BY MONTH-INDEX.
05 NAME PIC X(10).
05 ABBREV PIC X(3).
05 DAYS PIC 99.
77 CURRENT-MONTH PIC 99.
77 NEXT-31-DAY-MONTH PIC 99.
SET MONTH-INDEX TO CURRENT-MONTH.
SET MONTH-INDEX UP BY 1.
SEARCH MONTH
AT END MOVE 1 TO MONTH-INDEX
SEARCH MONTH
AT END MOVE 0 TO NEXT-31-DAY-MONTH
WHEN DAYS(MONTH-INDEX) = 31
SET NEXT-31-DAY-MONTH TO MONTH-INDEX
END-SEARCH
WHEN DAYS(MONTH-INDEX) = 31
SET NEXT-31-DAY-MONTH TO MONTH-INDEX
END-SEARCH
要查找多维表格,要将SEARCH放到PERFORM中。
01 TABLE-DATA.
03 DIM-1 OCCURS 10 TIMES INDEXED BY X1.
05 DIM-2 OCCURS 20 TIMES INDEXED BY X2.
07 NAME PIC X(20).
07 STATE PIC XX.
...
PERFORM VARYING X1 FROM 1 BY 1 UNTIL X1 > 20
SET X2 TO 1
SEARCH DIM-2
WHEN STATE(X1,X2) = "AL" ....
WNEH STATE(X1,X2) = "AZ" ....
END SEARCH
END-PERFORM.
还有一种SEARCH是对有关键字的表格进行查找,和上面的查找差不多,主要是WHEN 条件中要用关键字作为查找条件。比如说关键字为A,则必须有WHEN A = .....