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 (包括更多示例)。
我正在尝试将用“;”分隔的输入行解串到一个数组中。但是我无法显示第一个“;”之后的每个单词。
基本上,输入: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 (包括更多示例)。