Search code examples
arraysstringcobol

Unstring a field which is of variable length in COBOL and separated by spaces


I'm having a field which will have variable values or no values. The field is

Ws-var = "12 11 87 98"

Here "12 11" needs to be one pair and "87 98" should be the other pair. The variable is dynamic and might contain more sets of such pairs. As of now I wrote the COBOL code as

Unstring ws-field delimited by space into
    Ws-temp1,ws-temp2,ws-temp3,ws-temp4. 

These values will be further used for processing as pairs only. This code will work when there are 2 pairs of values. But, if conditions change in future to require more such pairs, I thought of implementing with an array, moving each pair to a output field, and reading the next pair. Can you suggest ways to implement it?


Solution

  • You can use string pointers and a table to achieve this. With UNSTRING the string pointer specifies where to start with the UNSTRING and is automatically increased to the point after the next delimiter (mind that this may also mean: when the target field is "full").

           77  str-ptr                USAGE BINARY-LONG UNSIGNED.
           01  var-pair.
               05  var-a              PIC 9(04). *> or whatever your size is
               05  filler             PIC X.     *> to have exactly one space
               05  var-b              PIC 9(04). *> or whatever your size is
          *> for "standard" COBOL use 01 CONSTANT AS - or just hard-wire below
           78  var-pair-length        VALUE LENGTH OF var-pair.
           78  var-pair-max           VALUE 500. *> or whatever you need
           77  var-pair-cnt           USAGE BINARY-LONG UNSIGNED.
           01  var-pairs.
               05  pair               PIC X(var-pair-length) OCCURS  0 TO var-pair-max
                                                             DEPENDING ON var-pair-cnt.
        
    
               MOVE 1 TO str-ptr
               PERFORM var-pair-cnt FROM 1 BY 1
                       UNTIL var-pair-cnt > var-pair-max
                  MOVE SPACES TO ws-temp1, ws-temp2
                  UNSTRING ws-var DELIMITED BY ALL SPACE
                      INTO ws-temp1, ws-temp2
                      WITH POINTER str-ptr
                  IF ws-temp1 = SPACES
                     EXIT PERFORM
                  END-IF
                  MOVE FUNCTION NUMVAL (ws-temp1) TO var-a
                  MOVE FUNCTION NUMVAL (ws-temp2) TO var-b
                  MOVE var-pair                   TO pair (var-pair-cnt)
               END-PERFORM
    
    

    You'll likely need to add some validation and/or adjust the definitions, but I think the code above transports the idea.