抑制前导零

时间:2015-12-10 18:35:21

标签: cobol mainframe

我们使用数字编辑的图片子句Z(4).99来压制前导零。它用空格替换前导零。我的问题是,我们可以删除那些空格并仅显示实际值而不带前导空格吗?

我有ws-amount,即图9(09)v99。如果我向它移动100,它将看起来像00000010000.但在我的报告中,我需要它显示为"贷款金额$ 100.00"。

4 个答案:

答案 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动词STRINGUNSTRING已经存在,所以应该广泛使用。对于常规文本的操作,它们有很多用途。

   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.