STRING and UNSTRING:
The STRING statement allows the programmer to concatenate several fields together into one field. The DELIMITED BY clause allows the programmer to specify a character or characters that mark the end of the field. The STRING will take only those characters that precede the character(s) in the DELIMITED clause and move them to the INTO field (receiving field). Note that the delimiter is a character literal enclosed in quotes. DELIMITED BY SIZE means that the entire field is brought over to the INTO area. The first data to move into the INTO/receiving field moves against the left wall of the field. The next sending field moves data in immediately to the right of the data that is already there etc.
The POINTER option means that the data moves into the INTO field starting at the position specified by the pointer. The pointer is incremented by 1 every time a character is moved into the INTO area. Obviously pointer cannot be 0 or a negative number and it cannot exceed the length of the INTO/receiving field. The ON OVERFLOW option allows you to specify what to do when a problem occurs. The problem can be that the end of the INTO/receiving field has been reached and there is still data to be moved or that the pointer field is out of range. If there is no ON OVRFLOW then the STRING or UNSTRING is abandoned and processing moves to the next logical instruction.
The UNSTRING statement allows you to take the data in one field and break it out into several fields. With the UNSTRING, again only the characters that precede the character(s) in the DELIMITED clause are moved to the fields specified in the INTO. Looking at the layout for the verb, you can see it has several options. The ALL clause means that two or more of the character specified as a delimiter will be treated as if there was only one and none of the delimiter characters will be moved to the INTO/receiving fields. Notice that you can have an OR so that you can check to see if the delimiter is one thing or another. If you want to keep the delimiter you can use the DELIMITER in clause to receive the character that was found and used as the delimiter.
There is also a COUNT IN option that allows the programmer to count the number of characters that get moved into the INTO/receiving field. You can specify a different count field for each of the receiving fields. The WITH POINTER option can designate a position in the sending field that will be the first character that is sent. This means if the pointer is 5, the first four characters will not be sent. Every time a character is sent to the receiving field, the POINTER is incremented by 1. The TALLYING IN option counts how many of the receiving fields actually used. This usually means received data but if there were two delimiters next to each other and you didn't use the all you could conceivably end up with an empty field that would be counted as used. The ON OVERFLOW will be used when all of the data cannot be unstrung successfully or the pointer is out of range.
Examples:
COBOL Code | Data and results |
STRING FST-NAME DELIMITED BY " " " " DELIMITED BY SIZE LST-NAME DELIMITED BY " " INTO WHOLE-NAME. |
FST-NAME = SUSAN LST-NAME = ANDERSON WHOLE-NAME = SUSAN ANDERSON |
UNSTRING WHOLE-NAME DELIMITED BY " " INTO FST-NAME LST-NAME. |
WHOLE-NAME= SUSAN ANDERSON FST-NAME = SUSAN LST-NAME = ANDERSON |
UNSTRING WHOLE-FIELD DELIMITED BY "/" INTO LNAM FNAM STREET CITY STATE ZIP. |
WHOLE-FIELD = LEE/ANN/123 EAST ST /BOSTON/MA/02114 LNAM=LEE FNAM=ANN STREET=123 EAST ST CITY =BOSTON STATE=MA ZIP=02114 |
STRING FLD1 FLD2 FLD3 DELIMITED BY SIZE INTO FLD123. |
FLD1=AB*CD FLD2=JKL*MN FLD3=S*TUV FLD123=AB*CDJKL*MNS*TUV |
STRING FLD1 FLD2 FLD3 DELIMITED BY "*" INTO FLD123. |
FLD1=AB*CD FLD2=JKL*MN FLD3=S*TUV FLD123=ABJKLS |
STRING FLD1 FLD2 FLD3 DELIMITED BY "*" INTO FLD123 POINTER PT1. |
FLD1=AB*CD FLD2=JKL*MN FLD3=S*TUV PT1=3 (before execution) FLD123=^^ABJKLS PT1=9 (after execution) |
UNSTRING FLD123 DELIMITED BY "*" INTO FLD1 FLD2 FLD3 FLD4. |
FLD123=AB*CDJKL*MNS*TUV FLD1=AB FLD2=CDJKL FLD3=MNS FLD4=TUV |
UNSTRING FLD123 DELIMITED BY "*" INTO FLD1 COUNT IN CT1 FLD2 COUNT IN CT2 FLD3 COUNT IN CT3 FLD4 COUNT IN CT4. |
FLD123=AB*CDJKL*MNS*TUV FLD1=AB CT1=2 FLD2=CDJKL CT2=5 FLD3=MNS CT3=3 FLD4=TUV CT4=3 |
UNSTRING FLD123 DELIMITED BY "*" INTO FLD1 COUNT IN CT1 FLD2 COUNT IN CT2 FLD3 COUNT IN CT3 FLD4 COUNT IN CT4 WITH POINTER PT1 TALLYING IN TAL1. |
FLD123=AB*CDJKL*MNS*TUV PT1=1 (before execution) FLD1=AB CT1=2 FLD2=CDJKL CT2=5 FLD3=MNS CT3=3 FLD4=TUV CT4=3 PT1=16 (after execution) TAL1=4 |
UNSTRING FLDABC DELIMITED BY "/" OR "*" INTO FLD1 DELIMITER IN DEL1 FLD2 DELIMITER IN DEL2. |
FLDABC=XYZ/ABC*DEF FLD1=XYZ DEL1=/ FLD2=ABC DEL2=* |
UNSTRING FLDABC DELIMITED BY "/" OR "*" INTO FLD1 DELIMITER IN DEL1. |
FLDABC=XYZ/ABC*DEF FLD1=XYZ DEL1=/ |
UNSTRING FLDXYZ DELIMITED BY ALL "*" INTO FLD1 FLD2. |
FLDXYZ=JKLMN****STUV FLD1=JKLMN FLD2=STUV |
STRING FLDA FLDB FLDX DELIMITED BY WS-DEL INTO FLDABC. |
FLDA=AB&XYZ FLDB=LMN&OP FLDC=ST&V WS-DEL=& FLDABC=ABLMNST |