IBM主机技术一本通
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

6.10 STRING命令

STRING命令用来将源字符串中的字符从左到右逐个串联起来并存放在目的字符串中。串联的过程中不会用空格填充目的字符串多余的位置。当有多个源字符串时,串联会从源字符串最左边的字符串开始传送。一条STRING语句可以代替多条MOVE语句的功能。

下面是STRING命令的语法。

其中的一些选项是:

● Source1等是源字符串,其数据类型的USAGE必须是DISPLAY的。

● DELIMITED BY短语指定字符串的限制。

✧ SIZE:传送整个的源字符串。

INTO:指定目的字符串。

POINTER:指定要插入到接收字符串的起始位置,变量Pointer#必须说明为整数类型,且足够存放接收字符串的长度加1。

ON OVERFLOW:说明出现溢出时要执行的语句(StatementBlock)。STRING命令出现溢出的情况如下。

✧ Pointer#变量的值小于1。

✧ 执行STRING命令时,Pointer#变量的值大于接收字段的长度,即目的字符串已经填满但在源字符串中依然有字符串没有使用完。

● NOT ON OVERFLOW短语指定没有出现溢出时要执行的命令。

END-STRING:结束STRING命令。

假定我们要将深圳的电话号码26558888加上中国和深圳的地区代码(086-755)2655-8888,可以使用下面的命令:

        01 WS-IN-PHONE.
            03 WS-COUNTRY-CODE   PIC 9(03).
            03 WS-CITY-CODE     PIC 9(04).
            03 WS-LOCAL-PHONE   PIC 9(08).
            03 WS-OUT-PHONE     PIC X(25).
        PROCEDURE DIVISION.
                  STRING '(' DELIMITED BY SIZE
                    WS-COUNTRY-CODE DELIMITED BY SIZE
                    '-' DELIMITED BY SIZE
                    WS-CITY-CODE(2:3) DELIMITED BY SIZE
                    ')' DELIMITED BY SIZE
                    WS-LOCAL-PHONE(1:4) DELIMITED BY SIZE
                    '-' DELIMITED BY SIZE
                    WS-LOCAL-PHONE(5:4) DELIMITED BY SIZE
                    INTO WS-OUT-PHONE
              END-STRING

6.10.1 程序例子(STRING命令)

下面的程序和报表结果演示了STRING命令的用法。第49行到第58行的命令是用来对电话号码加工处理的,STRING命令将国家代码和城市代码用括号括起来,效果显示在报表的第2行,似乎一切都是不错的,唯一的缺憾是,国家代码和城市代码之间的零应该去掉,这在第60行到第69行的代码中做了改进,去掉了国家代码和城市代码之间的零并加了一个连字符(-),这样产生的结果显示在报表的第3行,应该是令人满意的结果。

接下来的STRING命令都是对字符串‘SZ AMAZING!’和‘WORLD IS FLAT!’进行操作的。目的字符串的初始值全面置成了星号(*),用来清楚地告诉我们,STRING操作引起了原来字符串的哪些字符发生了变化。

第72行到第77行的STRING语句直接将两个源字符串的内容串联起来,由于目的字符串的长度正好是两个源字符串的长度之和,因此,结果是完美的,两个源字符串的内容完完整整地置换了目的字符串中的内容,不多不少。报表中的第4行说明了这一点。

第79行到第84行的STRING命令对第1个源字符串使用了DELIMITED BY SPACE代替DELIMITED BY SIZE,这两个短语的含义是不同的,BY SIZE表示源字符串中的所有字符都要传送到目的字符串中,而BY SPACE则表示只要字符串中第1个空格(Space)之前的字符,这样,源字符串‘SZ AMAZING!’中只有SZ传送到了目的字符串中。这样的结果显示在报表的第5行。由于源字符串传送的长度不够长,因此,目的字符串的后面依然保留了几个星号(*)。

第86行到第91行的命令与上面的完全类似,不过这次取了第1个源字符串的全部而只取了第2个源字符串的一段,这也是通过使用DELIMITED BY SPACE代替DELIMITED BY SIZE做到的。运行的结果对应于报表的第6行。

第93行到第99行的代码使用了WITH POINTER选项,目的是将源字符串中的字符从目的字符串的每个特定的位置开始传送,而不是从默认的第1个字符位置开始传送,但遗憾的是,由于程序中为指针指定了负值(-1),这是没有意义的,因为目的字符串的位置必须使用正整数来表达,结果也很明显,程序出现了溢出错误。报表的第7行告诉了我们这一点。

第8行的报表告诉我们,第101行的代码也出错了,但这次的POINTER指定的值是8,应该没有问题,那问题出在什么地方呢?其实很简单,这次的问题出在目的字符串的长度不够长,虽然,表面上看,目的字符串的长度正好是两个源字符串的长度之和,但由于使用了WITH POINTER选项,而且POINTER指定的值为8,这样,源字符串的字符就要从目的字符串的第8位开始传送,当然,目的字符串就会溢出了。

第110行到第116行的代码使用了DELIMITED BY ‘IS’,既不是我们前面使用的SPACE,也不是常用的SIZE。这样的例子告诉我们,你在使用STRING命令时可以使用任何有效的字符串作为分隔符!命令的执行结果显示在报表的第9 行,注意结果的前后都有星号(*),因为我们在命令中既使用了WITH POINTER选项而且填充目的字符串的长度又不够长,才会产生这样的效果。

在接下来的两个STRING例子中,我们引进了足球(Football)和世界杯(Cup)。第118 行到第125行的STRING命令出错了,原因是字符串足球(‘FOOTBALL’)太长了,目的字符串存放不下,导致了报表第10行的出错信息。第127行到第134行的命令则成功执行了,因为只是将字符串世界杯(‘CUP’)加到目的字符串中,而且POINTER的位置也由原来的8 提前到了5,这样就产生了第11 行的完美结局‘****SZ AMAZING!WORLD CUP*’,好像深圳或山寨拿了世界杯一样。

下面是各种STRING命令的完整源代码,值得你仔细读一读。

        000001  IDENTIFICATION DIVISION.
        000002 *
        000003  PROGRAM-ID. STRING1.
        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(20) VALUE SPACES.
        000019    03 RPT-HEAD-MOVE  PIC X(25) VALUE '*MAGIC REPORT(STRING)*'.
        000020    03 FILLER          PIC X(27) VALUE SPACES.
        000021  01 WS-ITEMS.
        000022    03 WS-POINTER       PIC S9(04) USAGE IS BINARY.
        000023    03 WS-S-STRING1     PIC X(11) VALUE 'SZ AMAZING!'.
        000024    03 WS-S-STRING2     PIC X(14) VALUE 'WORLD IS FLAT!'.
        000025    03 WS-D-STRING1   PIC X(25) VALUE ALL '*'.
        000026    03 WS-D-STRING2   PIC X(25) VALUE ALL '*'.
        000027    03 WS-D-STRING3   PIC X(25) VALUE ALL '*'.
        000028    03 WS-D-STRING4   PIC X(25) VALUE ALL '*'.
        000029    03 WS-D-STRING5   PIC X(25) VALUE ALL '*'.
        000030    03 WS-D-STRING6   PIC X(25) VALUE ALL '*'.
        000031    03 WS-D-STRING7   PIC X(25) VALUE ALL '*'.
        000032    03 WS-D-STRING8   PIC X(25) VALUE ALL '*'.
        000033 *
        000034  01 WS-IN-PHONE.
        000035    03 WS-COUNTRY-CODE   PIC 9(03).
        000036    03 WS-CITY-CODE     PIC 9(04).
        000037    03 WS-LOCAL-PHONE   PIC 9(08).
        000038    03 WS-OUT-PHONE     PIC X(25).
        000039 *
        000040  PROCEDURE DIVISION.
        000041 * SHOW HEADING AND SUBHEADING
        000042      DISPLAY RPT-HEADING
        000043 * SOURCE DATA
        000044      MOVE 86                   TO WS-COUNTRY-CODE
        000045      MOVE 755                  TO WS-CITY-CODE
        000046      MOVE 26558888              TO WS-LOCAL-PHONE
        000047      .
        000048 * STRING 1
        000049      STRING '(' DELIMITED BY SIZE
        000050            WS-COUNTRY-CODE DELIMITED BY SIZE
        000051            WS-CITY-CODE DELIMITED BY SIZE
        000052            ')' DELIMITED BY SIZE
        000053            WS-LOCAL-PHONE(1:4) DELIMITED BY SIZE
        000054            '-' DELIMITED BY SIZE
        000055            WS-LOCAL-PHONE(5:4) DELIMITED BY SIZE
        000056            INTO WS-OUT-PHONE
        000057      END-STRING
        000058      DISPLAY WS-OUT-PHONE
        000059 * STRING 2
        000060      STRING '(' DELIMITED BY SIZE
        000061            WS-COUNTRY-CODE DELIMITED BY SIZE
        000062            '-' DELIMITED BY SIZE
        000063            WS-CITY-CODE(2:3) DELIMITED BY SIZE
        000064            ')' DELIMITED BY SIZE
        000065            WS-LOCAL-PHONE(1:4) DELIMITED BY SIZE
        000066            '-' DELIMITED BY SIZE
        000067            WS-LOCAL-PHONE(5:4) DELIMITED BY SIZE
        000068            INTO WS-OUT-PHONE
        000069      END-STRING
        000070      DISPLAY WS-OUT-PHONE
        000071 * STRING 3
        000072      STRING WS-S-STRING1 DELIMITED BY SIZE
        000073            WS-S-STRING2 DELIMITED BY SIZE
        000074            INTO WS-D-STRING1
        000075            ON OVERFLOW DISPLAY "STRING OVERFOLW!"
        000076            NOT ON OVERFLOW DISPLAY WS-D-STRING1
        000077      END-STRING
        000078 * STRING 4
        000079      STRING WS-S-STRING1 DELIMITED BY SPACE
        000080            WS-S-STRING2 DELIMITED BY SIZE
        000081            INTO WS-D-STRING2
        000082            ON OVERFLOW DISPLAY "STRING OVERFOLW!"
        000083            NOT ON OVERFLOW DISPLAY WS-D-STRING2
        000084      END-STRING
        000085 * STRING 5
        000086      STRING WS-S-STRING1 DELIMITED BY SIZE
        000087            WS-S-STRING2 DELIMITED BY SPACE
        000088            INTO WS-D-STRING3
        000089            ON OVERFLOW DISPLAY "STRING OVERFOLW!"
        000090            NOT ON OVERFLOW DISPLAY WS-D-STRING3
        000091      END-STRING
        000092 * STRING 6
        000093      MOVE -1           TO WS-POINTER
        000094      STRING WS-S-STRING1 DELIMITED BY SIZE
        000095            WS-S-STRING2 DELIMITED BY SIZE
        000096            INTO WS-D-STRING4 WITH POINTER WS-POINTER
        000097            ON OVERFLOW DISPLAY "STRING OVERFOLW!"
        000098            NOT ON OVERFLOW DISPLAY WS-D-STRING4
        000099      END-STRING
        000100 * STRING 7
        000101      MOVE 8            TO WS-POINTER
        000102      STRING WS-S-STRING1 DELIMITED BY SIZE
        000103            WS-S-STRING2 DELIMITED BY SIZE
        000104            INTO WS-D-STRING5 WITH POINTER WS-POINTER
        000105            ON OVERFLOW DISPLAY "STRING OVERFOLW!"
        000106            NOT ON OVERFLOW DISPLAY WS-D-STRING5
        000107      END-STRING
        000108 *
        000109 * STRING 8
        000110      MOVE 5            TO WS-POINTER
        000111      STRING WS-S-STRING1 DELIMITED BY SIZE
        000112            WS-S-STRING2 DELIMITED BY 'IS'
        000113            INTO WS-D-STRING6 WITH POINTER WS-POINTER
        000114            ON OVERFLOW DISPLAY "STRING OVERFOLW!"
        000115            NOT ON OVERFLOW DISPLAY WS-D-STRING6
        000116      END-STRING
        000117 * STRING 9
        000118      MOVE 8            TO WS-POINTER
        000119      STRING WS-S-STRING1 DELIMITED BY SIZE
        000120            WS-S-STRING2 DELIMITED BY 'IS'
        000121            'FOOTBALL'   DELIMITED BY SIZE
        000122            INTO WS-D-STRING7 WITH POINTER WS-POINTER
        000123            ON OVERFLOW DISPLAY "STRING OVERFOLW!"
        000124            NOT ON OVERFLOW DISPLAY WS-D-STRING7
        000125      END-STRING
        000126 * STRING 10
        000127      MOVE 5            TO WS-POINTER
        000128      STRING WS-S-STRING1 DELIMITED BY SIZE
        000129            WS-S-STRING2 DELIMITED BY 'IS'
        000130            'CUP'   DELIMITED BY SIZE
        000131            INTO WS-D-STRING8 WITH POINTER WS-POINTER
        000132            ON OVERFLOW DISPLAY "STRING OVERFOLW!"
        000133            NOT ON OVERFLOW DISPLAY WS-D-STRING8
        000134      END-STRING
        000135 *
        000136      STOP RUN.

6.10.2 程序运行结果(STRING命令)

        000001                   *MAGIC REPORT(STRING)*
        000002  (0860755)2655-8888
        000003  (086-755)2655-8888
        000004  SZ AMAZING!WORLD IS FLAT!
        000005  SZWORLD IS FLAT!*********
        000006  SZ AMAZING!WORLD*********
        000007  STRING OVERFOLW!
        000008  STRING OVERFOLW!
        000009  ****SZ AMAZING!WORLD ****
        000010  STRING OVERFOLW!
        000011  ****SZ AMAZING!WORLD CUP*