6.11 UNSTRING命令
UNSTRING命令正好与STRING命令相反,用来将单个字符串分解成多个字符串。一条UNSTRING命令可以完成多条MOVE语句的功能。
UNSTRING命令不停地从源数据串往目的数据串中传送数据,直到在源数据串中碰到分隔符或目的数据串填满为止。这时,下一个目的数据串变成接收字段,系统继续传送直到再次在源数据中碰到分隔符或目的字符串填满为止。从源数据到目的数据之间的传送遵守字符串传送(Move)语句的规则,不够的部分会用空格填满。
UNSTRING语句会在下面的任何一种情况下结束。
● 源字符串中的所有字符都检查完。
● 所有目的字符串处理完毕。
● 处理过程中碰到了错误。
下面显示的是UNSTRING命令的语法。
UNSTRING SourceStr [DELIMITED BY [ALL] Delim [OR [ALL] Delim]…] INTO {DestStr [DELIMITER IN HoldDelim] [COUNT IN CharCounter]} … [WITH POINTER Pointer] [TALLYING IN DestCounter] [ON OVERFLOW StatementBlock] [NOT ON OVERFLOW StatementBlock] [END-UNSTRING]
其中的一些选项是:
● SourceStr:指定要分解的源字符串。
● DELIMITED BY短语指定字符串的限制。
✧ Delim:指定分隔符。
● INTO:指定目的字符串。
● DELIMITER IN:与特定的目的字符串相关。
✧ HoldDelim:保存源字符串中碰到的分隔符。
● COUNT IN:与特定的目的字符串有关。
✧ CharCounter:返回传送到目的字符串中的字符的个数。
● WITH POINTER:记录源字符串中下一个要处理的字符(非分隔符)的位置。
✧ Pointer:必须存放足够源字符串的长度。
● TALLYING IN:每个UNSTRING命令只能使用一个TALLYING短语。
✧ DestCounter:保存受UNSTRING操作影响的目的字符串的个数。
● ON OVERFLOW:是否溢出。UNSTRING命令在下列情况下程序会出现溢出的状况。
✧ UNSTRING命令执行时,指针(变量POINTER)没有指向源字符串中的字符位置。
✧ 所有的目的字符串已经处理完了,但源字符串中还有字符没有用到。
● ALL:使用ALL短语时,系统将连续的相同的分隔符当成一个分隔符对待。
比如,为了将下面的长地址分隔为3行不同的内容,可以使用下面的UNSTRING命令。
000015 WORKING-STORAGE SECTION. 000016 * 000017 77 WS-LONG-ADDRESS PIC X(80) VALUE 'ROOM 702,BLK D 000018- TREASARY TOWER! SHATIN TERRITORY! HONG KONG, CHINA'. 000019 01 WS-DETAIL-ADDRESS. 000020 03 WS-ROAD PIC X(30). 000021 03 WS-CITY PIC X(30) 000022 03 WS-COUNTRY PIC X(20). 000023 * 000024 PROCEDURE DIVISION. 000025 UNSTRING WS-LONG-ADDRESS DELIMITED BY ALL '!' 000026 INTO WS-ROAD,WS-CITY,WS-COUNTRY 000027 END-UNSTRING.
6.11.1 程序例子(UNSTRING命令)
下面的程序和报表结果演示了UNSTRING命令的用法。第46行到第56行的命令简单明了,用来将自由格式的长地址分解成3段,第1段是门牌号码,第2段是路名,最后一段是城市和国家名。用户输入自由格式的地址时必须在这3段分隔的地方输入逗号(,),这样程序才能将它们正确地分解出来。报表的第3行到第5行显示了命令执行后的结果。
第2个和第3个UNSTRING分别从程序段的第59行到第71行和第74行到第86行,都使用了WITH POINTER选项,但赋给指针变量WS-POINTER的值分别是0和-1,这不能指向正确的字符串位置,因而都出现了溢出错误。报表的第7行和第9行反映了这一点。
第89行到第102行的UNSTRING命令使用了正确的指针变量,因而结果也是令人满意的,在报表的第11行到第13行显示了分解后的地址,同时在第14行显示了指针变量的值88。它代表什么?它表示源字符串中下一次要处理的字符的位置,但是我们的字符串总共87 个字符,当所有源字符串中的字符都处理完时,UNSTRING命令也就结束了,因而不会再去处理后面的字符,但作为计数器,则是正确的。
第105行到第124行的命令使用了3个COUNT IN短语,每个短语对应一个目的字段,在报表的第20、21和22行分别显示的是31、26和28,这又是什么意思?它的含义是,从源字符串中分别传送了31、26和28个字符到对应的目的字符串中。对于这些数字你也许没有什么感觉,甚至觉得挺无厘头的,但是当你碰到要处理格式要求严格的SWIFT报文时,你就很有可能要用到它们了。
最后一个UNSTRING命令(从第126行到第146行),使用了TALLYING IN选项,它的目的是告诉我们UNSTRING命令一共影响(修改)了几个目的字段,这在报表的最后一行(第31行)给出了答案,3,表明我们需要的3个目的字段都有斩获了。
下面是使用各种UNSTRING命令的完整代码,希望对你有所帮助。
000001 IDENTIFICATION DIVISION. 000002 * 000003 PROGRAM-ID. UNSTR1. 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(UNSTRING)*'. 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-POINTER PIC S9(04) USAGE IS BINARY. 000033 03 WS-COUNT1 PIC S9(04) COMP. 000034 03 WS-COUNT2 PIC S9(04) COMP. 000035 03 WS-COUNT3 PIC S9(04) COMP. 000036 03 WS-TALLY-COUNT PIC S9(04) COMP. 000037 03 WS-D-STRING1 PIC X(35) VALUE ALL '*'. 000038 03 WS-D-STRING2 PIC X(35) VALUE ALL '*'. 000039 03 WS-D-STRING3 PIC X(35) VALUE ALL '*'. 000040 * 000041 PROCEDURE DIVISION. 000042 * SHOW HEADING AND SUBHEADING 000043 DISPLAY RPT-HEADING 000044 . 000045 * UNSTRING 1 000046 UNSTRING WS-INPUT-ADDRESS DELIMITED BY "," 000047 INTO WS-D-STRING1 WS-D-STRING2 WS-D-STRING3 000048 ON OVERFLOW 000049 DISPLAY RPT-NEWLINE 000050 DISPLAY 'STRING ERR,OVERFLOW' 000051 NOT ON OVERFLOW 000052 DISPLAY RPT-NEWLINE 000053 DISPLAY WS-D-STRING1 000054 DISPLAY WS-D-STRING2 000055 DISPLAY WS-D-STRING3 000056 END-UNSTRING 000057 . 000058 * UNSTRING 2 000059 MOVE -1 TO WS-POINTER 000060 UNSTRING WS-INPUT-ADDRESS DELIMITED BY "," 000061 INTO WS-D-STRING1 WS-D-STRING2 WS-D-STRING3 000062 WITH POINTER WS-POINTER 000063 ON OVERFLOW 000064 DISPLAY RPT-NEWLINE 000065 DISPLAY 'STRING ERR,OVERFLOW' 000066 NOT ON OVERFLOW 000067 DISPLAY RPT-NEWLINE 000068 DISPLAY WS-D-STRING1 000069 DISPLAY WS-D-STRING2 000070 DISPLAY WS-D-STRING3 000071 END-UNSTRING 000072 . 000073 * UNSTRING 3 000074 MOVE 0 TO WS-POINTER 000075 UNSTRING WS-INPUT-ADDRESS DELIMITED BY "," 000076 INTO WS-D-STRING1 WS-D-STRING2 WS-D-STRING3 000077 WITH POINTER WS-POINTER 000078 ON OVERFLOW 000079 DISPLAY RPT-NEWLINE 000080 DISPLAY 'STRING ERR,OVERFLOW' 000081 NOT ON OVERFLOW 000082 DISPLAY RPT-NEWLINE 000083 DISPLAY WS-D-STRING1 000084 DISPLAY WS-D-STRING2 000085 DISPLAY WS-D-STRING3 000086 END-UNSTRING 000087 . 000088 * UNSTRING 4 000089 MOVE 1 TO WS-POINTER 000090 UNSTRING WS-INPUT-ADDRESS DELIMITED BY "," 000091 INTO WS-D-STRING1 WS-D-STRING2 WS-D-STRING3 000092 WITH POINTER WS-POINTER 000093 ON OVERFLOW 000094 DISPLAY RPT-NEWLINE 000095 DISPLAY 'STRING ERR,OVERFLOW' 000096 NOT ON OVERFLOW 000097 DISPLAY RPT-NEWLINE 000098 DISPLAY WS-D-STRING1 000099 DISPLAY WS-D-STRING2 000100 DISPLAY WS-D-STRING3 000101 DISPLAY 'POINTER IS:' WS-POINTER 000102 END-UNSTRING 000103 . 000104 * UNSTRING 5 000105 MOVE 1 TO WS-POINTER 000106 UNSTRING WS-INPUT-ADDRESS DELIMITED BY "," 000107 INTO WS-D-STRING1 COUNT IN WS-COUNT1 000108 WS-D-STRING2 COUNT IN WS-COUNT2 000109 WS-D-STRING3 COUNT IN WS-COUNT3 000110 WITH POINTER WS-POINTER 000111 ON OVERFLOW 000112 DISPLAY RPT-NEWLINE 000113 DISPLAY 'STRING ERR,OVERFLOW' 000114 NOT ON OVERFLOW 000115 DISPLAY RPT-NEWLINE 000116 DISPLAY WS-D-STRING1 000117 DISPLAY WS-D-STRING2 000118 DISPLAY WS-D-STRING3 000119 DISPLAY 'POINTER IS:' WS-POINTER 000120 DISPLAY 'COUNT1 IS:' WS-COUNT1 000121 DISPLAY 'COUNT2 IS:' WS-COUNT2 000122 DISPLAY 'COUNT3 IS:' WS-COUNT3 000123 END-UNSTRING 000124 . 000125 * UNSTRING 6 000126 MOVE 1 TO WS-POINTER 000127 UNSTRING WS-INPUT-ADDRESS DELIMITED BY "," 000128 INTO WS-D-STRING1 COUNT IN WS-COUNT1 000129 WS-D-STRING2 COUNT IN WS-COUNT2 000130 WS-D-STRING3 COUNT IN WS-COUNT3 000131 WITH POINTER WS-POINTER 000132 TALLYING IN WS-TALLY-COUNT 000133 ON OVERFLOW 000134 DISPLAY RPT-NEWLINE 000135 DISPLAY 'STRING ERR,OVERFLOW' 000136 NOT ON OVERFLOW 000137 DISPLAY RPT-NEWLINE 000138 DISPLAY WS-D-STRING1 000139 DISPLAY WS-D-STRING2 000140 DISPLAY WS-D-STRING3 000141 DISPLAY 'POINTER IS:' WS-POINTER 000142 DISPLAY 'COUNT1 IS:' WS-COUNT1 000143 DISPLAY 'COUNT2 IS:' WS-COUNT2 000144 DISPLAY 'COUNT3 IS:' WS-COUNT3 000145 DISPLAY 'TALLY-COUNT IS:' WS-TALLY-COUNT 000146 END-UNSTRING 000147 . 000148 * 000149 STOP RUN.
6.11.2 程序运行结果(UNSTRING命令)
000001 *MAGIC REPORT(UNSTRING)* 000002 *----------------------* 000003 19/F CHINA MERCHANTS BANK TOWER 000004 NO. 7088 SHENNAN BOULEVARD 000005 SHENZHEN GUANGDONG 518 PRC 000006 *----------------------* 000007 STRING ERR,OVERFLOW 000008 *----------------------* 000009 STRING ERR,OVERFLOW 000010 *----------------------* 000011 19/F CHINA MERCHANTS BANK TOWER 000012 NO. 7088 SHENNAN BOULEVARD 000013 SHENZHEN GUANGDONG 518 PRC 000014 POINTER IS:0088 000015 *----------------------* 000016 19/F CHINA MERCHANTS BANK TOWER 000017 NO. 7088 SHENNAN BOULEVARD 000018 SHENZHEN GUANGDONG 518 PRC 000019 POINTER IS:0088 000020 COUNT1 IS:0031 000021 COUNT2 IS:0026 000022 COUNT3 IS:0028 000023 *----------------------* 000024 19/F CHINA MERCHANTS BANK TOWER 000025 NO. 7088 SHENNAN BOULEVARD 000026 SHENZHEN GUANGDONG 518 PRC 000027 POINTER IS:0088 000028 COUNT1 IS:0031 000029 COUNT2 IS:0026 000030 COUNT3 IS:0028 000031 TALLY-COUNT IS:0003