Cobol - 如何确定PIC N字段中内容的长度和位置?

时间:2016-03-29 12:18:24

标签: cobol

我发现我倾向于以太大的块来攻击问题,所以这里是我的 尝试从更小,更具体的东西开始。

我专门与PIC N领域合作,这些领域是国家领域。我需要为我正在处理的程序确定该字段中内容的长度和位置。

我所谈论的具体领域定义如下:

05 Bank-CODE PIC N(10).

可能有前导空格,可能有尾随空格。我也需要在某些时候对嵌入式空间进行测试。

基本上,目标是能够在没有空格的情况下处理此字段的内容。

现在,我知道如何确定字段本身的长度: 05 BANK-CODE PIC N(10). 05 BK-LENGTH PIC S9(04) COMP. MOVE LENGTH OF BANK-CODE TO BK-LENGTH COMPUTE BK-LENGTH = FUNCTION LENGTH (BANK-CODE)

我只是不知道如何确定BANK-CODE中内容的长度和位置。

1 个答案:

答案 0 :(得分:4)

您正在寻找的是" trim",或者允许您从字段中修剪前导和尾随空格的信息。

COBOL没有。除非如前所述,否则您使用的是像GnuCOBOL这样的编译器。但我猜您正在使用IBM的企业COBOL。如果是,则名称和特定版本将显示在编译器输出列表的每个页面的顶部。

仅仅因为COBOL没有修剪,不会阻止你。这只意味着你需要代码。

这里有一些来自"那里" (S8833TR.pdf的搜索引擎,链接很长,很长一段时间)并找到客户情况编码提示的部分:

MOVE ' This is string 1 ' TO TEXT1
COMPUTE POS1 POS2 = 0
INSPECT TEXT1
   TALLYING POS1
   FOR LEADING SPACES
INSPECT FUNCTION REVERSE(TEXT1)
   TALLYING POS2
   FOR LEADING SPACES
MOVE TEXT1(POS1:LENGTH OF TEXT1 - POS2 - POS1)
 TO TEXT2

MOVE ' This is string 1 ' TO TEXT1
PERFORM VARYING POS1 FROM 1 BY 1
  UNTIL TEXT1(POS1:1) NOT = SPACE
END-PERFORM
PERFORM VARYING POS2 FROM LENGTH OF TEXT1
   BY -1 UNTIL TEXT1(POS2:1) NOT = SPACE
END-PERFORM
COMPUTE LEN = POS2 - POS1 + 1
MOVE TEXT1(POS1 : LEN) TO TEXT2 (1 : LEN)

您将在文档中看到,正如您所知,FUNCTION REVERSE存在一些性能影响(第一个代码块比第二个代码块慢31%),但要小心避免它。如果运行速度较慢,则更容易编码和理解。如果您的子程序将被大量使用,那么考虑性能是值得的。

该代码由IBM的Tom Ross提供。

汤姆的代码使用"参考修改"。如果起始位置和长度中的任何一个或两者都是可变的,则可以在编译时(如果已知起始位置和长度)或在运行时即时定义字段的子字段。引用修改是一种非常快速的访问数据的方法。它也是一种非常懒惰和草率的访问数据的方式,它会混淆代码(可能会有一些意见显示出来,其他人可能暂时不会持有这些意见)。

下一段代码使用类似这样的代码来代替引用修改:

       01  the-text                        PIC X(30).
       01  FILLER 
           REDEFINES the-text.
           05  FILLER 
               OCCURS 30 TIMES.
               10  the-byte-of-text        PIC X.

然后可以通过下标来引用文本字节,而不是引用的组项(文本)。

对于参考修改和下标,POS1可能会被定义相同。或者它可以。我要去PIC 99 BINARY(BINARY / COMP / COMP-4在Enterprise COBOL中是相同的),但你的同事可能会坚持PIC S9(4)COMP(老习惯很难)。

现在,如果你想要更快:

       PERFORM 
         VARYING                    POS1 
           FROM                     1 
           BY                       1 
         UNTIL                      ( NOT TEXT1-BYTE-IS-SPACE 
                                       ( POS1 ) )
       END-PERFORM 
       MOVE TEXT1 ( POS1 : )        TO TEXT2 

实际上,汤姆的代码中缺少一部分,即TEXT2的初始化。

此代码(我的)通过不使用"长度"来解决这个问题。在参考修改中。为什么不? COBOL字段是固定长度的(除了可变长度字段),因此您无法摆脱"#34;摆脱"尾随空格。对于那个例子,那么,不用费心去寻找尾随空格,并使用最后的MOVE来确保TEXT2中没有数据从之前的代码执行中留下(在Tom的例子中会有) )。

请注意,我使用了REDEFINES和数据名称作为子脚本(POS1)和88级条件名称。除了更快,您还可以使代码更清晰。在限制范围内,您可以同时执行这两项操作。

对于你的任务,你想知道尾随空格的长度:

示例的一个问题是,它们通常不会完整,就像缺少初始化一样。另一件尚未完成的事情是所有代码都假定至少有一个非空白存在(因为文字被用作源)。这通常是不现实的,在你的情况下绝对没有用。

人们会经常通过包括&#34来处理更一般的情况;确保我没有逃避结束"在PERFORM的终止条件下。但是,多个条件更难理解,运行速度更慢。

       IF field-in-use-is-blank
           PERFORM                  no-field-to-deal-with
       ELSE
           PERFORM                  field-to-deal-with
       END-IF

立即制作两个不同的案例。在字段到交易中,您可以知道至少有一个非空白字符。在无场交易中你知道整个领域都是空白的。

field-in-use-is-blank是您所在领域的88级条件名称。

   01  your-field                          PIC X(40).
       88  field-in-use-is-blank           VALUE SPACE.

请注意,我使用的名称仅用于说明。我总是为你的实际目的建议有意义的名字。

       PERFORM 
         VARYING                    POS2 
           FROM                     LENGTH OF TEXT1 
           BY -1 
         UNTIL                      ( TEXT1-SPACE-CHECK 
                                       ( POS2 )
                                     NOT EQUAL TO SPACE )
       END-PERFORM 
       COMPUTE LEN                  = ( POS2 
                                      - POS1 ) 
                                      + 1

从场地末端向后退,你不能使用88级。

现在你有LEN。我会为所有事情使用不同的名字,但这就是我。

以下是相关的数据定义:

   01  FILLER REDEFINES TEXT1. 
       05  FILLER OCCURS 50 TIMES. 
           10  TEXT1-SPACE-CHECK           PIC X. 
               88  TEXT1-BYTE-IS-SPACE     VALUE SPACE.

   01  LEN                          COMP   PIC S9(4).
   01  POS1                         COMP   PIC S9(4).
   01  POS2                         COMP   PIC S9(4).

TEXT1只是一个50字节的PIC X字段。皮肤有很多种方法。上面的代码显示了POS1如何在引用修改中使用,以及如何用于下标。 LEN,POS1和POS2的尺寸和类型是最好的猜测。它们都可能是BINARY(让我现代化,因为它只是一个打字的东西......)PIC 99.有些情况下,这个定义比原始定义更有效,否则相同。不要期望说服你的任何一位老年人。

COBOL主要是一个"团队"事情。按照他们在您的网站上完成的方式做事。如果当地"标准"是穷人或过时的,你总是可以尝试改变它们,但编码其他代码(技术)的方式意味着更容易理解团队。显然,使用有意义的名称本身就是一个好处,与技术无关。

以上是针对PIC X(或PIC A,但您不太可能看到这些)字段。 PIC N的不同之处是什么?只需FUNCTION LENGTH而不是LENGTH OF

然而,PIC N存在潜在的性能问题。在幕后,如果有必要,编译器会将National转换为字母数字,然后再返回。为了表现,只有数字和普通的拉丁字母,我只在最后一刻将所有内容转换为PIC N.这可以像简单的MOVE一样少,编译器会为您生成代码。

忘了添加你已经显示一个链接到"微调"同样:https://codereview.stackexchange.com/q/69220/21548