cobol - 如何摆脱字符串中的尾随和嵌入空格?

标签 cobol

我正在编写一个程序,将国家和国际帐号转换为IBAN帐号。首先,我需要形成一个字符串:银行ID +分行ID +帐号+ ISO国家/地区代码,而这些字段中可能没有尾随空格。但是,并非每个帐号都有相同的长度,有些帐号具有分支标识符,而有些帐号没有分支标识符,因此,我总是以这些字段的结尾空格结尾。

我的工作存储如下所示:

      01 Input-IBAN.
          05 BANK-ID                    PIC N(10) VALUE "LOYD".
          05 BRANCH-ID                  PIC N(10) VALUE "     ".
          05 ACCOUNT-NR                 PIC N(28) VALUE "012345678912   ". 
          05 COUNTRY-CODE               PIC N(02) VALUE "GB".
      01 Output-IBAN                    PIC N(34).


我为示例添加了一些值;实际上,这取决于输入。分支代码是可选的,因此在示例中将其留空。

我基本上想从这些输入串在一起:
"LOYD 012345678912 GB"

对此:
"LOYD012345678912GB"

有谁知道这样做的方法不会导致性能问题?我曾考虑过使用FUNCTION REVERSE,然后使用INSPECT来计算前导空格。但是我听说这是一个很慢的方法。有人有什么想法吗?也许是一个有关如何使用上述想法的例子?

编辑:
我被告知基本字段可能包含嵌入的空间。

最佳答案

现在,我看到您在数据中嵌入了空白。到目前为止,您都没有答案。吉尔伯特“挤出”嵌入的空白,在每个字段中第一个空白之后,我的数据将丢失。

但是,仅需指出,如果您以任何方式生成“ IBAN”,我真的不相信您可以嵌入空白。例如,https://en.wikipedia.org/wiki/International_Bank_Account_Number#Structure
特别:


通过电子传输时,IBAN不应包含空格。
打印时,以四个字符为一组,用四个字符隔开
单个空格,最后一组长度可变


如果您的源数据在字段级别具有嵌入的空格,那么您需要将该行引用回去以决定要做什么。假设您收到正确的答案(在字段级别没有嵌入的空白),那么两个现有答案都将重新出现在表格上。您可以通过(逻辑上)将LENGTH OF更改为FUNCTION LENGTH并处理输出溢出的任何可能性来修改Gilbert's。

使用STRING时,您必须再次处理输出溢出的可能性。

原始答案基于没有嵌入空格的假设。



我假设您在构成您的结构的基本项目中没有嵌入空格,因为它们是由不包含嵌入空格的标准值提供的。

       MOVE SPACE                   TO OUTPUT-IBAN
       STRING                       BANK-ID 
                                    BRANCH-ID 
                                    ACCOUNT-NR 
                                    COUNTRY-CODE 
         DELIMITED                  BY SPACE 
         INTO                       OUTPUT-IBAN 


STRING仅复制值,直到用完要复制的数据,因此有必要在STRING之前清除OUTPUT-IBAN。

当在每个源字段中遇到第一个SPACE时,将结束从每个源字段复制数据。如果字段完全是空格,则不会从该字段复制任何数据。

几乎可以肯定,STRING会导致运行时例程被执行,并且这样做会有一些开销。 Gilbert LeBlanc的示例可能会稍快一些,但是使用STRING时,编译器会自动处理所有字段的所有长度。因为您有“国家”字段,所以请确保使用图形常数空间(或空格,它们是相同的),而不要使用您认为包含空格" "的文字值。可以,但是不包含国家/地区空间。

如果STRING的结果大于34个字符,则多余的字符将被安静地截断。如果要处理此问题,STRING带有ON OVERFLOW短语,您可以在这种情况下指定要执行的操作。如果使用ON OVERFLOW或NOT ON OVERFLOW,则应使用END-STRING范围终止符。句号/句点也将终止STRING语句,但是当像这样使用时,永远不能在ON / NOT ON的情况下在任何类型的条件语句中使用。

不要使用句号/句号终止范围。

COBOL没有“字符串”。除非数据填满该字段,否则您不能消除定长字段中的尾随空格。当数据短时,输出IBAN将始终包含尾随空格。



如果您实际上要在字段级别嵌入空白:

首先,如果您想“挤出”嵌入的空白以使它们不会出现在输出中,那么我想不出一种比Gilbert更为简单的方法(使用COBOL)。

否则,如果要保留嵌入的空白,除了对尾随空白进行计数之外,别无选择,以便可以计算每个字段中实际数据的长度。

COBOL实现确实具有语言扩展。不清楚您使用的是哪个COBOL编译器。如果碰巧是AcuCOBOL(现在来自Micro Focus),则INSPECT支持TRAILING,您可以用这种方式计算尾随空白。 GnuCOBOL还支持INSPECT上的TRAILING,此外还具有有用的内在函数TRIM,您可以使用它在STRING语句中精确地执行所需的操作(修剪尾随空白)。

       move space                   to your-output-field
       string function 
               trim 
                ( your-first-national-source 
                  trailing )
              function 
               trim 
                ( your-second-national-source 
                  trailing )
              function 
               trim 
                ( your-third-national-source 
                  trailing )
              ...
         delimited                  by size
         into                       your-output-field


请注意,除了定义中的PIC N外,代码与使用字母数字字段的代码相同。

但是,对于标准COBOL 85代码...

您提到使用FUNCTION REVERSE后跟INSPECT。 INSPECT可以计算前导空格,但按标准不能计数尾随空格。因此,您可以反转字段中的字节,然后计算前导空格。

您有国家数据(PIC N)。与此不同的是,不是需要计数的字节,而是由两个字节组成的字符。由于编译器知道您正在使用PIC N字段,因此只有一件事可以使您跳闸-特殊寄存器LENGTH OF对字节进行计数,因此需要FUNCTION LENGTH来对字符进行计数。

国家数据为UTF-16。当一个字节恰好代表一个可显示的字符时,这恰好意味着每个字符的两个字节恰好是“ ASCII”。在EBCDIC机器上的z / OS上运行也没关系,因为编译器将自动为文字或字母数字数据项进行必要的转换。

       MOVE ZERO                    TO a-count-for-each-field 
       INSPECT FUNCTION 
                REVERSE 
                 ( each-source-field )
         TALLYING                   a-count-for-each-field 
          FOR LEADING               SPACE 


在为每个字段执行其中一项之后,可以使用引用修改。

如何为此使用引用修改?

首先,您必须要小心。其次,你没有。

第二,首先:

MOVE SPACE                   TO output-field
STRING field-1 ( 1 : length-1 )
       field-2 ( 1 : length-2 )
  DELIMITED BY               SIZE
  INTO                       output-field


如果可能/必要,再次处理溢出。

也可以使用简单的MOVE和参考修改,例如此答案https://stackoverflow.com/a/31941665/1927206,其问题与您的问题重复。

为什么要小心点?同样,根据先前链接的答案,理论上参考修改的长度不能为零。

实际上,它可能会起作用。一般而言,COBOL程序员似乎非常热衷于引用修改,以至于他们不必费心地阅读它,因此不必担心零长度不是标准的,也不必担心它不是标准的,因为它“有效”。目前。直到编译器更改。

如果您使用的是Enterprise COBOL V5.2或更高版本(也可能是V5.1,我只是没有检查过),那么可以通过编译器选项确保零长度引用修改的工作方式如下:预期。

该答案涵盖了其他一些实现任务的方法(如果嵌入的空白可能存在并且在输出中很重要)。使用National时,请始终注意使用FUNCTION LENGTH(计数字符),而不是LENGTH OF(计数字节)。通常,LENGTH OF和FUNCTION LENGTH给出相同的答案。对于多字节字符,则不是。

关于cobol - 如何摆脱字符串中的尾随和嵌入空格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36133761/

相关文章:

COBOL 中的 XML 具有嵌套表和不同的子项

cobol - CALL 参数(省略?文字?)

python - 如何将Python变量转换为等效的cobol组变量?

cobol - GnuCOBOL PIC 999V99 - 意外结果?

c++ - COBOL 到 C++ 数据转换

cobol - 遇到错误但不知道为什么还要学习 COBOL

cobol - 制作屏幕 (COBOL)

cobol - 错误 : syntax error, 意外 “FILE” ,预期 “end of file”

java - C# 中的 COBOL 到 Java 转换器

db2 - 如何在 cics map 中显示表数据