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