6.12 INSPECT语句
INSPECT命令从左至右扫描源字符串并根据TALLYING、REPLACING或CONVERTING短语的控制对源字符串计数或置换。INSPECT命令的行为可以通过使用LEADING、FIRST、BEFORE和AFTER短语而得到修正。BEFORE和AFTER短语后面可以跟上LEADING、CHARACTERS、FIRST或CONVERTING短语。由于TALLYING短语既可以单独出现,也可以同REPLACING短语一起使用,所以我们将这两种格式一起讲解。
TALLYING用来计算特定字符在源字符串中出现的次数。下面是INSPECT TALLYING语句的语法(格式1和格式3)。
其中的选项包括如下几项。
● SourceStr:指定要计数的源字符串,它可以是以下几种。
✧ 字符型的数据项。
✧ USAGE为DISPLAY的数字型数据项。
✧ 外部浮点数据项。
● Counter:计数器字段,用来存放特定字符在字符串中出现的次数,它必须定义为正整数,在INSPECT语句执行前,你必须对它的值初始化。
● Delim1:指定要计数的字符,其类型必须如下。
✧ 字符型的基本数据项。
✧ USAGE为DISPLAY的数字型数据项。
✧ 外部浮点数据项。
✧ 如果是文字常数,必须是非数字型的。
● CHARACTERS:当指定本项,而又既没有指定BEFORE,又没有指定AFTER选项时,则对于被检查数据项(源字符串),即SourceStr中的每个字符(包括空白字符)计数器(Counter)都会加1,这样,执行INSPECT命令的结果就是源字符串中有多少个字符,则计数器的值就是多少。
● ALL:当指定本项,而又既没有指定BEFORE,又没有指定AFTER选项时,则从左至右扫描源字符串,对于被检查数据项(源字符串),即SourceStr中的每一个不重复的特定字符(Delim)计数器(Counter)都会加1。
● LEADING:将比较字符Compard1与源字符串SourceStr当前位置的相同个数字符比较,当第1个匹配项找到时,计数器Counter加1,其他匹配不算。匹配项一旦找到,源字符串的指针都会向前移动于比较字符Compard1字符个数的位置。
● BEFORE:只检查分隔符(Delim2)之前(左边)的字符串。
● AFTER:只检查分隔符(Delim2)之后(右边)的字符串。
当INSPECT命令中同时指定TALLYING和REPLACING短语时,就是我们所说的第3 种格式的INSPECT命令。这时的INSPECT语句相当于在执行INSPECT TALLYING(格式1的INSPECT命令)后紧接着执行INSPECT REPLACING(格式2的INSPECT命令)。
● FIRST:只对格式3,即INSPECT TALLYING REPLACING格式有效。FIRST表示只使用置换字符Replace1置换源字符串SourceStr中第1次出现的比较字符串Compard2。
INSPECT REPLACING,即第2 种格式的INSPECT语句的功能,是使用特别的字符(Replace2Char置换填充源字符串中的全部或部分指定的字符(CompareChar)。当使用REPLACING CHARACTERS时,填充字符Replace2Char只能是1个字符。
下面是第2种格式的INSPECT语句的语法(格式2)。
INSPECT CONVERTING,即第4种格式的INSPECT语句的功能,是使用特别的字符将源字符串中的字符使用对照表的方法进行转换。对照表由字符串CompareChar和ConvertChar来定义,它们的字符个数必须相同。
CompareChar的第1个字符对应于ConvertChar中的第1字符,以此类推。INSPECT REPLACING语句会从左到右逐个检查源字符串中的字符,并按照对照表的内容做对应的转换。
下面是第4种格式的INSPECT语句的语法(格式4)。
6.12.1 程序例子(INSPECT命令)
我们依然采用演示报表的形式讲述INSPECT语句的使用。在第47行和第48行的程序中,由于使用了短语FOR CHARACTERS,其功能就是检查字符串中有多少个字符,结果简单明了。WS-S-STRING1的长度是21个字符,这从它的PIC描述中都可以看出来,结果显示在报表的第3行。
第53行到第54行的INSPECT语句检查WS-S-STRING1中一共有多少个‘C’(WS-CPR-STRING1),结果显示在报表的第5行,即一共有两个“C”字符。这里要留意的是给WS-COUNT1的赋值,如果不赋初值,WS-COUNT1的值会变成23,即21+2,因为上一条INSPECT语句已经将WS-COUNT1的值变成了21。
第59行到第61行的INSPECT语句出现了AFTER短语,它的含义是要从源字符串的‘CHINA’之后开始计算字符‘C’的个数,结果就由上面的2变成了1,因为在WS-S-STRING1中,字符串‘CHINA’之后只有一个‘C’。
第66行到第67行的INSPECT语句和第72行到第73行的INSPECT语句,都使用了LEADING短语,分别在字符串WS-S-STRING1的最前面找字符‘C’和数字1,结果是字符‘C’没有找到而数字1找到了,原因很简单,因为WS-S-STRING1的第1个字符是‘1’,所以前面的INSPECT语句没有找到而后面的则找到了。它们的结果分别对应报表的第9行和第11行。
第80行到第82行的INSPECT语句使用了REPLACING短语,目的是将WS-S-STRING1中的所有字符‘C’置换成字符‘Z’并统计字符串中有多少个数字1,结果显示在报表的第13行到第15行,源字符串中的所有字符‘C’都置换成了字符‘Z’,而字符串中只有一个数字1。
第88行到第89行的INSPECT短语使用了CONVERTING短语,目的是根据对照表将源字符串中的字符A置换为1、B置换为2、H置换为3、S置换为4和Z置换为5。报表的最后两行即第17行和第18行,显示了置换前和置换后的结果。
下面是使用各种INSPECT语句的完整COBOL程序,值得你好好研究一下。
000001 IDENTIFICATION DIVISION. 000002 * 000003 PROGRAM-ID. INSPECT1. 000004 AUTHOR. NEWMAN LV. 000005 * 000006 ENVIRONMENT DIVISION. 000007 * 000008 INPUT-OUTPUT SECTION. 000009 * 000010 DATA DIVISION. 000011 * 000012 000013 FILE SECTION. 000014 * 000015 WORKING-STORAGE SECTION. 000016 * 000017 01 RPT-HEADING. 000018 03 FILLER PIC X(10) VALUE SPACES. 000019 03 RPT-HEAD-MOVE PIC X(25) VALUE '*MAGIC REPORT(INSPECT)*'. 000020 03 FILLER PIC X(27) VALUE SPACES. 000021 01 RPT-NEWLINE. 000022 03 FILLER PIC X(10) VALUE SPACES. 000023 03 RPT-HEAD-MOVE PIC X(25) VALUE '*----------------------*'. 000024 03 FILLER PIC X(27) VALUE SPACES. 000025 01 WS-INPUT-ADDRESS. 000026 03 WS-S-STRING1 PIC X(21) VALUE '19/F CHINA MERCHANTS '. 000027 03 WS-S-STRING2 PIC X(46) 000028 VALUE 'BANK TOWER,NO. 7088 SHENNAN BOULEVARD,SHENZHEN'. 000029 03 WS-S-STRING3 PIC X(20) 000030 VALUE 'GUANGDONG 518 PRC'. 000031 01 WS-ITEMS. 000032 03 WS-COUNT1 PIC S9(04) COMP. 000033 03 WS-COUNT2 PIC S9(04) COMP. 000034 03 WS-COUNT3 PIC S9(04) COMP. 000035 03 WS-TALLY-COUNT PIC S9(04) COMP. 000036 03 WS-CPR-STRING1 PIC X(1) VALUE 'C'. 000037 03 WS-CPR-STRING2 PIC 9(1) VALUE 1. 000038 03 WS-MAP-STRINGI PIC X(5) VALUE 'ABHSZ'. 000039 03 WS-MAP-STRINGO PIC X(5) VALUE '12345'. 000040 * 000041 PROCEDURE DIVISION. 000042 * SHOW HEADING AND SUBHEADING 000043 DISPLAY RPT-HEADING 000044 . 000045 * INSPECT1 000046 MOVE ZEROS TO WS-COUNT1 000047 INSPECT WS-S-STRING1 TALLYING WS-COUNT1 000048 FOR CHARACTERS 000049 DISPLAY RPT-NEWLINE 000050 DISPLAY 'WS-COUNT1 IS:' WS-COUNT1 000051 * INSPECT2 000052 MOVE ZEROS TO WS-COUNT1 000053 INSPECT WS-S-STRING1 TALLYING WS-COUNT1 000054 FOR ALL WS-CPR-STRING1 000055 DISPLAY RPT-NEWLINE 000056 DISPLAY 'WS-COUNT1 IS:' WS-COUNT1 000057 * INSPECT3 000058 MOVE ZEROS TO WS-COUNT1 000059 INSPECT WS-S-STRING1 TALLYING WS-COUNT1 000060 FOR ALL WS-CPR-STRING1 000061 AFTER INITIAL 'CHINA' 000062 DISPLAY RPT-NEWLINE 000063 DISPLAY 'WS-COUNT1 IS:' WS-COUNT1 000064 * INSPECT4 000065 MOVE ZEROS TO WS-COUNT1 000066 INSPECT WS-S-STRING1 TALLYING WS-COUNT1 000067 FOR LEADING WS-CPR-STRING1 000068 DISPLAY RPT-NEWLINE 000069 DISPLAY 'WS-COUNT1 IS:' WS-COUNT1 000070 * INSPECT5 000071 MOVE ZEROS TO WS-COUNT1 000072 INSPECT WS-S-STRING1 TALLYING WS-COUNT1 000073 FOR LEADING WS-CPR-STRING2 000074 DISPLAY RPT-NEWLINE 000075 DISPLAY 'WS-COUNT1 IS:' WS-COUNT1 000076 * INSPECT6 000077 MOVE ZEROS TO WS-COUNT1 000078 DISPLAY RPT-NEWLINE 000079 DISPLAY 'BEFORE REPLACE IS:' WS-S-STRING1 000080 INSPECT WS-S-STRING1 TALLYING WS-COUNT1 000081 FOR LEADING WS-CPR-STRING2 000082 REPLACING ALL 'C' BY ‘Z' 000083 DISPLAY 'AFTER REPLACE IS:' WS-S-STRING1 000084 DISPLAY 'WS-COUNT1 IS:' WS-COUNT1 000085 * INSPECT7 000086 DISPLAY RPT-NEWLINE 000087 DISPLAY 'BEFORE CONVERT IS:' WS-S-STRING2 000088 INSPECT WS-S-STRING2 CONVERTING WS-MAP-STRINGI 000089 TO WS-MAP-STRINGO 000090 DISPLAY 'AFTER CONVERT IS:' WS-S-STRING2 000091 * 000092 STOP RUN.
6.12.2 程序运行结果(INSPECT命令)
000001 *MAGIC REPORT(INSPECT)* 000002 *----------------------* 000003 WS-COUNT1 IS:0021 000004 *----------------------* 000005 WS-COUNT1 IS:0002 000006 *----------------------* 000007 WS-COUNT1 IS:0001 000008 *----------------------* 000009 WS-COUNT1 IS:0000 000010 *----------------------* 000011 WS-COUNT1 IS:0001 000012 *----------------------* 000013 BEFORE REPLACE IS:19/F CHINA MERCHANTS 000014 AFTER REPLACE IS:19/F ZHINA MERZHANTS 000015 WS-COUNT1 IS:0001 000016 *----------------------* 000017 BEFORE CONVERT IS:BANK TOWER,NO. 7088 SHENNAN BOULEVARD,SHENZHEN 000018 AFTER CONVERT IS:21NK TOWER,NO. 7088 43ENN1N 2OULEV1RD,43EN53EN