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