COBOL 解串成数组

COBOL Unstring into an Array

我正在尝试将用“;”分隔的输入行解串到一个数组中。但是我无法显示第一个“;”之后的每个单词。

基本上,输入:Hello;Stack;Overflow


输出:值:2(因为有 2 个分号)


我记录的第一行Table:你好


我记录的第 2 行 Table:堆栈


我记录的第 3 行 Table:溢出

到目前为止我的代码:

*-------------------------------------------------------------
 LINKAGE SECTION.                                             
 01  X-INPUT-LINE                   PIC X(2000).              
 01  X-SEP-CHAR                     PIC X(1).                                     
 01  X-RET-TABLE.                                             
  02 CMAX                           PIC 9(5) COMP-3.          
  02 ENTRY-REC OCCURS 0 TO 9999 TIMES DEPENDING ON CMAX       
                                      INDEXED   BY CIDX.      
   04 ENTRY-REC2.                                             
    07 LINEVALUE                    PIC X(100).               

PROCEDURE DIVISION USING X-INPUT-LINE
                         X-SEP-CHAR  
                         X-RET-TABLE.

MAIN SECTION.
MN-00.       
INITIALIZE WERT.                                

INSPECT X-INPUT-LINE TALLYING WERT FOR ALL      
        X-SEP-CHAR.                             
MOVE X-INPUT-LINE TO VAL.                       

ADD 1 TO WERT.                                  
PERFORM WERT TIMES                              
MOVE WERT TO LINEVALUE OF X-RET-TABLE (WERT)    
     UNSTRING VAL DELIMITED BY ";"              
     INTO STRVAL                                
     END-UNSTRING                               


IF CMAX OF X-RET-TABLE < 9999                   
   ADD  1  TO CMAX OF X-RET-TABLE               
   MOVE STRVAL TO ENTRY-REC(CMAX OF X-RET-TABLE)

END-IF                                          
END-PERFORM.    

使用我的以下代码,我只能在我的示例中显示 "Hello",并且程序在 3 个不同的行中显示它 3 次。

Unstring 并不是这样工作的。如果您知道要解串的内容的字段名称,Unstring 将起作用。基本上你的代码中发生的是你 运行 unstring 3 次,因为 "hello" 是 unstring 中的第一件事,它被 unst运行g 3 次。如果你想做一些可扩展到数组的事情,你需要像这样编写一个循环:

01 WS-UNSTRING-FIELDS.
   05 WS-INPUT PIC X(1000).
   05 WS-SUB   PIC 9(4) COMP.
   05 WS-START PIC 9(4) COMP VALUE 1.
   05 WS-INDEX PIC 9(4) COMP VALUE 0.
   05 WS-ARRAY OCCURS 0 TO 9999 DEPENDING ON WS-INDEX.

PERFORM VARYING WS-SUB
           FROM 1 BY 1 
          UNTIL WS-SUB > FUNCTION LENGTH(WS-INPUT)
   IF WS-INPUT(WS-SUB:1) = ";"
      ADD 1 TO WS-INDEX

      MOVE WS-INPUT(WS-START:WS-SUB - 1) 
        TO WS-ARRAY(WS-INDEX)

      COMPUTE
         WS-START = WS-SUB + 1
      END-COMPUTE
   END-IF
END-PERFORM

我还没有真正的时间来测试它并确保它 100% 有效,但你需要一些类似的东西。我无论如何都会避免在这里使用 unstring。

当您确切知道有多少字段进入时,Unstring 非常有用。例如,假设您有与 MQ 系列交互的通用程序。作为该程序的输入,您可以传递一个字符串,其中包含类似于

的指令
QueueName/Action

然后您可以在此上下文中使用 unstring 将它们拆分为 2 个字段:

UNSTRING WS-INPUT DELIMITED BY "/"
   INTO WS-Q-NAME
        WS-ACTION
END-UNSTRING

假设这里的输入是:

THIS_IS_MY_QUEUE/DELETE

WS-Q-NAME 将具有 THIS_IS_MY_QUEUE_NAME 而 WS-ACTION 将具有 DELETE

您的原始代码几乎 有效。

主要问题是,您 UNSTRING 一个给定的变量并始终使用相同的起点。

他我们可以用WITH POINTER。用在 STRING 上,子句表示 "position where next character is stored",用在 UNSTRING 上,表示 "position where next character is read from"。

使用起始代码(添加调用者,实际上使用给定的分隔符而不是固定的“;”和结果的 DISPLAY),添加 here 我们为起点并使用它。

     UNSTRING X-INPUT-LINE DELIMITED BY X-SEP-CHAR
     INTO STRVAL
     END-UNSTRING

变成

     UNSTRING X-INPUT-LINE DELIMITED BY X-SEP-CHAR
     INTO STRVAL
     WITH POINTER STARTING-POINT
     END-UNSTRING

你还需要初始化一些部分,可以直接使用table项(只要你保证计数器不会太大),为你提供result (包括更多示例)。