【问题标题】:COBOL Unstring into an ArrayCOBOL 解串成数组
【发布时间】:2018-09-17 12:01:30
【问题描述】:

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

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


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


我的记录表第一行:你好


我的记录表的第 2 行:堆栈


我的记录表第 3 行:溢出

到目前为止我的代码:

*-------------------------------------------------------------
 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 次。

【问题讨论】:

标签: arrays string input record cobol


【解决方案1】:

您的原始代码几乎有效。

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

我们可以使用WITH POINTER。用于STRING 子句表示“存储下一个字符的位置”,用于UNSTRING 表示“读取下一个字符的位置”。

使用起始代码(添加调用者,实际上使用给定的分隔符而不是固定的“;”和结果的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

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

【讨论】:

  • 嗨@Simon Sobisch 首先,我从来不知道我们可以使用Cobol 的编码地来调用子程序。感谢您的认识。不过答案很好。
  • @SrinivasanJv 最简单的方法是像我一样将所有内容组合到一个编译单元中(使用END PROGRAM)。当您在编码场上“共享”时,您总是共享可能由多个来源组成的项目。要使多个源工作,您必须调整编译命令(最简单:更改为 cobc -m *.cob 并将运行命令更改为 cobcrun yourmain)。
  • 好主意。不知道为什么要执行 if 语句:IF WERT = 字符串长度,则可能不需要之前的 INSPLECT。
【解决方案2】:

Unstring 并不是这样工作的。如果您知道要解串的字段名称,解串将起作用。基本上你的代码中发生的事情是你运行 unstring 3 次,因为“hello”是 unstring 中的第一件事,它被 unstring 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 怎么样 MOVE INPUT TO REMIANDER ,然后 PERFORM UNTIL REMAINDER = ''UNSTRING REMAINDER [...] INTO ARRAY(IND) REMAINDER
  • WS-Sub 或 WS-Start 在我的源代码中到底是什么,我无法真正与您的答案联系起来。
  • @Brian WS-SUB 只是一个递增的索引,因此您可以一次检查字符串 1 个字符。 WS-START 只是跟踪每个分隔符后第一个字符的位置。
  • @piet.t 那将是另一种选择。就个人而言,我更喜欢子字符串循环的想法。我发现更容易理解它的工作原理。但是遍历子字符串是一种选择
  • @piet.t @SaggingRufus 使用UNSTRING 时需要注意的一点是,它将字符从源字符串复制到目标,直到满足终止数据移动的条件(在这种情况下,它的 ';')。因此,PERFORM UNTIL REMAINDER = ' 'UNSTRING REMAINDER INTO ARRAY(IND) REMAINDER 将导致无限循环,因为ARRAY(1) 将包含“Hello”而REMAINDER 将包含“STACK”。当 ARRAY(1) 的数据移动结束时,下一个目标字符串 REMAINDER 成为接收区域并复制字符,直到再次满足终止条件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 2012-05-15
  • 1970-01-01
相关资源
最近更新 更多