记录的格式为:
01 LAST-NAME PIC X(18).
01 FIRST-NAME PIC X(12).
01 MI-NAME PIC X(01).
当它们进来时,姓氏和名字当然可以是任何大小。
我需要将名称字段放在一起(没有尾随空格 - 但每个名称之间有一个空格)到一个工作存储字段中,长度为42个空格:
01 WS-FULL-NAME PIC X(42)
示例:
LAST-NAME = Smithington
FIRST-NAME = Edward
MI-NAME = H
期望的结果:
Edward H Smithington
如果Middle初始化为空白,我当然不包括它,所需的结果将是:
Edward Smithington
我有一个例程来确定每个名字字段的实际长度,它已经处理了尾随空格(*我不需要担心前导空格)(见下文):
01 W-SUB PIC 9(02) VALUE 0.
PROCESS-LAST-NAME.
PERFORM VARYING W-SUB FROM LENGTH OF LAST-NAME BY -1
UNTIL W-SUB LESS THAN 1
OR LAST-NAME(W-SUB:1) NOT = ' '
END-PERFORM
IF W-SUB > ZERO
MOVE LAST-NAME(1:W-SUB) TO ?????
'移动最后一个名字(1:W-SUB)到?????'是我被困'的地方。
即。如何将三个名字字段“拼凑”在一起产生渴望的结果= Edward H Smithington(*包括F,MI + L之间的空格)。
答案 0 :(得分:3)
您被要求使用STRING
执行此操作。反对对名称使用STRING的论点是名称可以包含嵌入空格。 DE LA HAYE
例如作为姓氏,' ST JOHN' (发音为sinjun)作为名字。也可能有拼写错误提供前导空白和嵌入式空白。你似乎知道你没有领先的空白,但真正的或错误的嵌入式空白使得STRING的简单使用更加棘手。
如果您可以保证没有领先或嵌入的空白(绝对保证),那么
IF MI-NAME EQUAL TO SPACE
STRING FIRST-NAME
DELIMITED BY SPACE
' '
DELIMITED BY SIZE
LAST-NAME
DELIMITED BY SPACE
INTO FULL-NAME
ELSE
STRING FIRST-NAME
DELIMITED BY SPACE
' '
DELIMITED BY SIZE
MI-NAME
DELIMITED BY SIZE
' '
DELIMITED BY SIZE
LAST-NAME
DELIMITED BY SPACE
INTO FULL-NAME
END-IF
在IF之前,您需要将空格移动到全名,否则当前名称比前一个名称短时,您将得到以前名称的一部分。
如果您不能保证缺少前导和嵌入空格,则必须使用引用修改字段作为名字和姓氏(每个长度一个),并使用DELIMITED BY SIZE。那么重点是什么?
01 W-FULL-NAME.
05 W-FIRST-NAME.
10 FILLER OCCURS 0 TO 12 TIMES
DEPENDING ON length-of-first-name.
15 FILLER PIC X.
05 SPACE-AFTER-FIRST-NAME PIC X.
05 W-MI-NAME.
10 FILLER OCCURS 0 TO 2 TIMES
DEPENDING ON length-for-mi.
15 FILLER PIC X.
05 W-LAST-NAME.
10 FILLER OCCURS 0 TO 18 TIMES
DEPENDING ON length-of-last-name.
15 FILLER PIC X.
你有两个PERFORMs来获取名字和姓氏的长度(已经是)。如果WS-MI-NAME是空格,则移动ZERO为mi-length,否则将其设为两个。
然后:
MOVE SPACE TO SPACE-AFTER-FIRST-NAME
MOVE FIRST-NAME TO W-FIRST-NAME
MOVE LAST-NAME TO W-LAST-NAME
MOVE MI-NAME TO W-MI-NAME
W-FULL-NAME是一个可变长度字段,以您想要的格式包含您想要的数据,然后您可以随意使用它。
通过改变"复杂性"通过数据定义进入DATA DIVISION,PROCEDURE DIVISION中的代码变得非常简单。
尝试一下,要查看格式化数据,请执行以下操作:
DISPLAY
">"
W-FULL-NAME
"<"
&gt;和&lt;只是为了准确地向您显示数据是什么(我总是在显示数据时这样做)。您将看到字段的长度随着不同的测试数据而变化(假设使用不同的长度数据进行测试......)。
以所有输入作为空格进行测试,您在SYSOUT后台数据集上看到这一点:
><
零长度字段。
通过参考修改,您可以这样做:
do your PERFORM to count the first-name trailing spaces
MOVE FIRST-NAME TO WS-FULL-NAME
ADD 1 WS-SUB
GIVING next-available-output
IF MI-NAME NOT EQUAL TO SPACE
MOVE MI-NAME TO WS-FULL-NAME
( next-available-output : 1 )
ADD 2 TO next-available-output
END-IF
do your PERFORM for the last-name
MOVE LAST-NAME TO WS-FULL-NAME
( next-available-output : W-SUB )
输出的第一个MOVE会将第一个名称复制到全名。两者都不需要被引用修改,效果将是除了名称的字符以外的其他目标字段将是空白的。
存在的字符数是已知的,因此可以通过添加一个来计算目标字段中数据的下一个可用位置。
第二个MOVE以是否存在任何中间初始数据为条件,如果是,则将MOVEd移动到上面计算的下一个可用输出位置。 MOVEd的字节数(一)在目标中受到限制。
第三个MOVE类似于第二个MOVE,除了无条件,MOVEd字节的限制是可变的。
以上变化是可能的。这是一种更简洁的方式,但在某种程度上取决于您的编译器。那你在用哪一个?
您可以简化尾随空白数量的计算:
01 W-SUB COMP PIC 9(4).
PROCESS-LAST-NAME.
MOVE ZERO TO W-SUB
IF LAST-NAME NOT EQUAL TO SPACE
MOVE FUNCTION LENGTH ( LAST-NAME )
TO W-SUB
PERFORM
UNTIL LAST-NAME ( W-SUB : 1 )
NOT EQUAL TO SPACE
SUBTRACT 1 FROM W-SUB
END-PERFORM
END-IF
这样,您就不必拥有双重终止条件。我重新定义了该字段,并使用下标而不是引用修改。我还重命名W-SUB以表明它包含数据的长度。