我们使用数字编辑的图片子句Z(4).99来压制前导零。它用空格替换前导零。我的问题是,我们可以删除那些空格并仅显示实际值而不带前导空格吗?
我有ws-amount,即图9(09)v99。如果我向它移动100,它将看起来像00000010000.但在我的报告中,我需要它显示为"贷款金额$ 100.00"。
答案 0 :(得分:3)
没有使用任何功能,因为它们与站点有关。
所以结果是一个怪物(我不会花更多的时间来改进它):
01 WS.
05 W-AMOUNT PIC 9(09)v99.
05 W-AMOUNT-ALPHA REDEFINES W-AMOUNT
PIC X(01) OCCURS 11.
05 W-DISPLAY PIC X(25).
05 W-DISPLAY-TAB REDEFINES W-DISPLAY
PIC X(01) OCCURS 25.
05 W-SENTENCE PIC X(12)
VALUE " TO PAY SOON".
05 W-SENTENCE-TAB REDEFINES W-SENTENCE
PIC X(01) OCCURS 12.
05 W-SENTENCE-LENGTH PIC 9(04) COMP-5.
05 W-POSITION-AMOUNT PIC 9(04) COMP-5.
05 W-POSITION-SENTENCE PIC 9(04) COMP-5.
05 W-POSITION-DISPLAY PIC 9(04) COMP-5.
05 W-LEADING-ZEROES PIC X(01).
88 STILL-LEADING-ZEROES VALUE "Y".
88 NO-MORE-LEADING-ZEROES VALUE "N".
接下来是:
PROCEDURE DIVISION.
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
CONTROL-PROCEDURE.
**
* The main procedure of the program
**
MOVE 15314.16 TO W-AMOUNT
PERFORM SUB-PROCEDURE
DISPLAY "LOAN AMOUNT $"
W-DISPLAY
MOVE 314.16 TO W-AMOUNT
PERFORM SUB-PROCEDURE
DISPLAY "LOAN AMOUNT $" W-DISPLAY
GOBACK
.
SUB-PROCEDURE.
MOVE ZERO TO W-POSITION-DISPLAY
W-POSITION-SENTENCE
MOVE SPACES TO W-DISPLAY
SET STILL-LEADING-ZEROES TO TRUE
PERFORM VARYING W-POSITION-AMOUNT
FROM 1 BY 1
UNTIL W-POSITION-AMOUNT > 9
IF (W-AMOUNT-ALPHA (W-POSITION-AMOUNT)
NOT EQUAL ZERO) THEN
SET NO-MORE-LEADING-ZEROES TO TRUE
END-IF
IF NO-MORE-LEADING-ZEROES THEN
ADD 1 TO W-POSITION-DISPLAY
MOVE W-AMOUNT-ALPHA (W-POSITION-AMOUNT)
TO W-DISPLAY-TAB (W-POSITION-DISPLAY)
END-IF
END-PERFORM
ADD 1 TO W-POSITION-DISPLAY
MOVE "." TO W-DISPLAY-TAB (W-POSITION-DISPLAY)
ADD 1 TO W-POSITION-DISPLAY
MOVE W-AMOUNT-ALPHA (W-POSITION-AMOUNT)
TO W-DISPLAY-TAB (W-POSITION-DISPLAY)
ADD 1 TO W-POSITION-DISPLAY
W-POSITION-AMOUNT
MOVE W-AMOUNT-ALPHA (W-POSITION-AMOUNT)
TO W-DISPLAY-TAB (W-POSITION-DISPLAY)
MOVE LENGTH OF W-SENTENCE TO W-SENTENCE-LENGTH
PERFORM W-SENTENCE-LENGTH TIMES
ADD 1 TO W-POSITION-DISPLAY
W-POSITION-SENTENCE
MOVE W-SENTENCE-TAB (W-POSITION-SENTENCE)
TO W-DISPLAY-TAB (W-POSITION-DISPLAY)
END-PERFORM
.
最终结果:
LOAN AMOUNT $15314.16 TO PAY SOON
LOAN AMOUNT $314.16 TO PAY SOON
有很多方法可以优化它(特别是我处理数字后面的数字的方式,它非常糟糕,但是我在看其他事情时这样做,所以我去了更简单的事情)。我不敢提交代码审查。但它确实有效。
答案 1 :(得分:3)
由于您似乎对审稿人可能会说的内容感到担忧,因此这里的代码实际上是您所要求的:
UNSTRING edited-field
DELIMITED BY ALL SPACE
INTO ignore-this
no-leading-space-field
我完全不确定如何难以复习。它确实需要这些定义:
01 edited-field PIC Z(10).99.
01 no-leading-space-field PIC x(13).
01 ignore-this PIC X.
如果您正在谈论性能优化,那么您需要处理gazzz0x2z在其答案中提供的代码。但是,您的审稿人将再次使用多行代码感到困惑。
自1974年COBOL标准以来,COBOL动词STRING
和UNSTRING
已经存在,所以应该广泛使用。对于常规文本的操作,它们有很多用途。
IDENTIFICATION DIVISION.
PROGRAM-ID. supspace.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 unedited-field PIC 9(9)v99.
01 edited-field PIC Z(10).99.
01 no-leading-space-field PIC x(13).
01 output-text PIC x(80).
01 text-intro PIC x(13) VALUE
"LOAN AMOUNT $".
01 text-outro PIC x(12) VALUE
" TO PAY SOON".
01 ignore-this PIC X.
PROCEDURE DIVISION.
MOVE 0.01 TO unedited-field
PERFORM the-work
MOVE 123.01 TO unedited-field
PERFORM the-work
MOVE ZERO TO unedited-field
PERFORM the-work
MOVE 123456789.01 TO unedited-field
PERFORM the-work
GOBACK
.
the-work.
PERFORM left-justify-edit
PERFORM assemble-output
DISPLAY
output-text
.
left-justify-edit.
MOVE unedited-field TO edited-field
UNSTRING edited-field
DELIMITED BY ALL SPACE
INTO ignore-this
no-leading-space-field
.
assemble-output.
MOVE SPACE TO output-text
STRING
text-intro
DELIMITED BY SIZE
no-leading-space-field
DELIMITED BY SPACE
text-outro
DELIMITED BY SIZE
INTO output-text
.
输出是:
LOAN AMOUNT $.01 TO PAY SOON
LOAN AMOUNT $123.01 TO PAY SOON
LOAN AMOUNT $.00 TO PAY SOON
LOAN AMOUNT $123456789.01 TO PAY SOON
请注意,编辑字段定义的时间比其他方式长一个字节,Z(10)而不是Z(9)。这是为了确保UNSTRING的DELIMITED始终至少有一个前导空间。
请注意,当结果值小于目标大小时,STRING 不会对其目标字段进行空格填充,因此如果结果值的长度可变,请清除目标字段之前使用STRING动词。
UNSTRING使用指定的分隔符将单个字段拆分为多个字段。
它的工作原理的关键是字段ignore-this和DELIMITED BY ALL SPACE,以及至少一个前导空间的保证存在。
ALL SPACE是从1到它所应用的字段大小的任意数量的空格。 UNSTRING中命名的任何分隔符都不包含在INTO字段中。前导分隔符的存在意味着第一个INTO字段将“包含”零长度数据,空间填充到第一个INTO字段的长度。第二个INTO字段将包含没有前导空格的数据,并将填充到该字段的长度。
STRING需要多个字段,这些字段可以由其中的数据分隔,并将它们放在一起以制作一个放在INTO字段中的数据,如果需要可以截断,但是没有空格-pad如果数据短于INTO字段。
在此处使用的STRING中,只有SPACE是分隔符,而不是ALL SPACE,因为单个空格足以分隔,代码将比使用ALL SPACE更快。
答案 2 :(得分:3)
这是一个示例,"到spec",但它可能不是"对于供应商",取决于编译器的年龄,如gazzz0x2z指出的那样。 (FUNCTION TRIM是在1989年的修正案中,所以26年后......)编辑:事实证明,这是一个错误。正如比尔所指出的那样,TRIM仅在2014年的最新规范中出现。我不知道'在哪里我不应该不喜欢。留下评论,羞愧地垂头丧气。
identification division.
program-id. left-just.
data division.
working-storage section.
01 amount pic 9(9)v99 value 100.00.
01 dollars pic $(8)9.99.
01 show-loan pic x(32).
procedure division.
move amount to dollars
string
"LOAN AMOUNT " delimited by size
function trim(dollars leading) delimited by size
into show-loan
display function trim(show-loan trailing)
goback.
end program left-just.
答案 3 :(得分:1)
这里使用了部分代码。
https://codereview.stackexchange.com/questions/69220/trim-functions-in-cobol
ws-amount pic 9(09)V99.
ws-formated-amount pic $$$$,$$$,$$9.99.
ws-output-message pic X(27).
MOVE ws-amount
TO ws-formated-amount.
MOVE ws-formated-amount
TO STR-VALUE-IN.
MOVE FUNCTION LENGTH (ws-formated-amount)
TO STR-LENGTH-IN.
PERFORM 5100-LTRIM.
MOVE SPACES TO ws-output-message.
STRING
'LOAN AMOUNT '
STR-VALUE-OUT (1:STR-LENGTH-OUT)
DELIMITED SIZE
INTO
ws-output-message
END-STRING.