delimiter - Cobol字符串由尾部空格分隔

标签 delimiter cobol

WORKING-STORAGE.
    FIRST-STRING    PIC X(15) VALUE SPACES.
    SECOND-STRING     PIC X(15) VALUE SPACES.
    OUTPUT-STRING     PIC X(31) VALUE SPACES.


如果FIRST-NAME = 'JON SNOW, ' and LAST-NAME = 'KNOWS NOTHING. ',我如何获得:

我想得到:

OUTPUT-STRING = 'JON SNOW, KNOWS NOTHING.         '


当我尝试:

String FIRST-STRING DELIMITED BY SPACES
       ' ' DELIMITED BY SIZE
       SECOND-STRING DELIMITED BY SIZE
       INTO OUTPUT-STRING


我得到'JON KNOWS NOTHING. '

当我尝试:

String FIRST-STRING DELIMITED BY SIZE
       SECOND-STRING DELIMITED BY SIZE
       INTO OUTPUT-STRING


我得到'JON SNOW, KNOWS NOTHING. '

我发现了一个由String FIRST-STRING DELIMITED BY ' '组成的调整(两个空格)
但是不能保证我的第一串不包含两个空格,这会导致丢失一部分。

最佳答案

首先,赞誉,因为很多人会以两个空格分隔,所以完全不用担心可能的后果。请注意,如果数据仅跟随一个尾随空格,您还将获得“意外”输出。还要注意,由于要插入空格以分隔数据,因此OUTPUT-STRING的字段定义短了一个字节。在两个字段都完全充满数据的情况下,您将丢失SECOND-STRING的最后一个字节。

COBOL是定长字段的语言(除非它们是可变的)。这意味着没有“标准”定界符,因此任何字符或值都可以出现在字段中的任何位置。此外,默认填充字符(源比目标字段短)是空格,这是单词的完全正常分隔符。

在您以及许多类似的情况下,您需要知道字段的实际数据部分的长度(不包括尾随空白)。

@ user4341206在其答案https://stackoverflow.com/a/31938039/1927206中建议使用一种非常常见的方法。

根据1985年的COBOL标准,INSPECT可用于计算前导空格,但不能用于计算尾随空格。首先可以使用FUNCTION REVERSE将尾随空格转换为前导空格,以便INSPECT可以对其进行计数。

一旦知道尾随空白的数量,就可以使用LENGTH OF特殊寄存器或FUNCTION LENGTH来确定固定长度字段的长度(在编译时都是(或者可以是,取决于编译器)) 。字段长度和尾随空白的数量之间的差异为您提供了数据的长度。

一旦有了数据的长度,请记住它可能是空白的(取决于数据的可能性),并且它的长度可能与字段相同

请注意,与从字段末尾开始的简单循环相比,如果您有大量数据,则可能不希望反转字段并使用INSPECT(可能是运行时例程)来计算尾随空白。

请注意,像AcuCOBOL这样的编译器(现在是Micro Focus的COBOL产品的一部分)具有语言扩展,该语言扩展提供了TRAILING作为INSPECT的选项。请注意,即使2014年COBOL标准也没有将TRAILING作为INSPECT的选项。

无论哪种方式,只要完成数据的长度即可。有点。

您可以在STRING语句中使用引用修改:

String FIRST-STRING ( 1 : length-field-you-define ) DELIMITED BY SIZE
       ' ' DELIMITED BY SIZE
       SECOND-STRING DELIMITED BY SIZE
   INTO OUTPUT-STRING


请注意,您应该能够删除BY SIZE,因为SIZE是默认设置,但对于读者来说确实很清楚。

您还可以在目标字段上使用带有参考修改的MOVE:

MOVE FIRST-STRING            TO OUTPUT-STRING  
                                 ( 1 : length-field-you-define )
MOVE SPACE                   TO OUTPUT-STRING  
                                 ( length-field-you-define + 1 : 1 )
MOVE SECOND-STRING           TO OUTPUT-STRING  
                                 ( length-field-you-define + 2 :  )


参考修改(在另一个答案中提到)存在一个特定问题,即您的长度字段不应为零。


长度的评估应得出一个非零的正整数。


在这种情况下,长度是引用修改表示法中第二个项目,在:之后。在这种情况下,这意味着您定义的长度字段不能为零,如果FIRST-STRING完全是空格,则可以将其计算为零。

潜在的问题是这样的:

MOVE FIRST-STRING            TO OUTPUT-STRING  
                                 ( 1 : length-field-you-define )


因此,根据您的数据(如果其中可能包含空白),您必须对此进行“保护”。

    IF FIRST-STRING EQUAL TO SPACE
        PERFORM                  COPY-SECOND-STRING-ONLY
    ELSE
        PERFORM                  CONCATENATE-FIRST-AND-SECOND
    END-IF
    ...
COPY-SECOND-STRING-ONLY.
    MOVE SECOND-STRING           TO OUTPUT-STRING
    .
CONCATENATE-FIRST-AND-SECOND.
    calculate length
    MOVE FIRST-STRING            TO OUTPUT-STRING  
                                    ( 1 : length-field-you-define )
    MOVE SPACE                   TO OUTPUT-STRING  
                                    ( length-field-you-define + 1 : 1 )
    MOVE SECOND-STRING           TO OUTPUT-STRING  
                                    ( length-field-you-define + 2 :  )
    .


如果您使用长度为零的引用修改,尽管结果可能会与您的编译器一起使用,但结果是不确定的。

使用STRING和可变长度字段的解决方案不会“失败”,因为引用修改之外的编译器对零长度项感到满意。

但是,出于两个原因,应该采用相同的“保护”:您将插入前导空格(“分隔符”);您将使代码明确,这样人们就不必问自己“第一个字段为空白时会发生什么”;您将节省处理时间。

这样,您的程序也可以更好地“描述您的数据”。除了“知道您的数据”是准确进行程序设计的必要条件外,您的程序对数据的描述越多,就越容易产生委托或遗漏错误,就越容易理解,并且越容易当数据结构发生变化时,它也会发生变化。

您也可以使用WITH POINTER选项查看STRING。首先,将FIRST-STRING移至OUTPUT-STRING(这也会将OUTPUT-STRING中未使用的字节清除为空格)。然后将一个添加到您定义的长度字段(用于中间空间)中,并在STRING中将其用于WITH POINTER。

尽管这是完全正确的,但如果使用它,这是一个发表评论的机会,因为许多经常使用STRING的人不知道使用WITH POINTER,所以请帮助他们。

另一种可能性是使用可变长度字段。

不幸的是,并非所有的COBOL编译器都使这变得容易。以其最纯粹的形式要求的“复杂ODO”是非标准的,但是是该语言的IBM扩展。

LINKAGE SECTION.
01  L-MAPPING-OF-OUTPUT-STRING.
    05  L-MOOS-FIRST-STRING.
        10  FILLER OCCURS 0 TO 15 TIMES
            DEPENDING ON length-field-you-define.
            15  FILLER                          PIC X.
    05  L-MOOS-SEPARATOR-SPACE                  PIC X.
    05  L-MOOS-SECOND-STRING                    PIC X(15).

    ...
    SET ADDRESS OF L-MAPPING-OF-OUTPUT-STRING
                             TO ADDRESS OF 
                                 OUTPUT-STRING  
    MOVE FIRST-STRING        TO L-MOOS-FIRST-STRING
    MOVE SPACE               TO L-MOOS-SEPARATOR-SPACE
    MOVE SECOND-STRING       TO L-MOOS-SECOND-STRING


如果您有大量数据,最快的方法是仅引用修改建议。我对引用修改的看法是,它倾向于混淆,因为人们倾向于以混淆(且不必要)的方式使用它。

我的首选是最后一种,其中PROCEDURE DIVISION代码非常简单:您可以在第一个字段中找到数据的长度;您只需做三个简单的MOVE。

也许您可以尝试每一种,以更加了解未来情况的可能性。

关于delimiter - Cobol字符串由尾部空格分隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31935955/

相关文章:

cobol - 如何在cobol中清除屏幕并将光标位置设置到屏幕末尾

cobol - MULTIPLY 的行为与我预期的不同

cobol - 如何删除连续文件中的最后3条记录

python - 是否可以将 AngularJS 与 Jinja2 模板引擎一起使用?

notepad++ - 在 Notepad++ 中定义单词分隔符

c - Arduino(C语言)解析带分隔符的字符串(通过串口输入)

c++ - 如何在 C++ 中读取一行并用 '!!"分隔它?

parsing - D3 删除千位逗号分隔符

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

cobol - EVALUATE TRUE block 中的条件是否按照它们列出的相同顺序进行评估?