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*