WORKING-STORAGE.
FIRST-STRING PIC X(15) VALUE SPACES.
SECOND-STRING PIC X(15) VALUE SPACES.
OUTPUT-STRING PIC X(31) VALUE SPACES.
Run Code Online (Sandbox Code Playgroud)
如果FIRST-NAME = 'JON SNOW, ' and LAST-NAME = 'KNOWS NOTHING. ',我怎样才能得到:
我想得到:
OUTPUT-STRING = 'JON SNOW, KNOWS NOTHING. '
Run Code Online (Sandbox Code Playgroud)
当我尝试:
String FIRST-STRING DELIMITED BY SPACES
' ' DELIMITED BY SIZE
SECOND-STRING DELIMITED BY SIZE
INTO OUTPUT-STRING
Run Code Online (Sandbox Code Playgroud)
我明白了 'JON KNOWS NOTHING. '
当我尝试:
String FIRST-STRING DELIMITED BY SIZE
SECOND-STRING DELIMITED BY SIZE
INTO OUTPUT-STRING
Run Code Online (Sandbox Code Playgroud)
我明白了 'JON SNOW, KNOWS NOTHING. '
我找到了一个由String FIRST-STRING DELIMITED BY ' '(两个空格)组成的调整但是不能保证我的FIRST-STRING不包含两个空格,这将导致丢失部分空格.
首先,值得赞扬的是,许多人会选择两个分隔的空间而不是完全关注可能的后果.请注意,如果数据后跟一个尾随空格,您还会得到"意外"输出.另请注意,OUTPUT-STRING的字段定义短一个字节,因为您要插入空格来分隔数据.如果两个字段都填满了数据,那么您将丢失SECOND-STRING的最后一个字节.
COBOL是一种固定长度字段的语言(除非它们是可变的).这意味着没有"标准"分隔符,因此任何字符或值都可以出现在字段中的任何位置.此外,默认填充字符(其中source比目标字段短)是空格,这是单词的完全正常的分隔符.
在您和许多类似的情况下,您需要知道字段的实际数据部分的长度(不包括尾随空白).
执行此操作的一种非常常见的方法是@ user4341206在其答案/sf/answers/2235662761/中的建议.
根据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
Run Code Online (Sandbox Code Playgroud)
注意,您应该能够删除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 : )
Run Code Online (Sandbox Code Playgroud)
引用修改存在一个特定问题(在另一个答案中提到),即长度字段不应为零.
长度的评估将产生正的非零整数.
此上下文中的长度是:引用修改符号后面的第二个项目.在这种情况下,它意味着你定义的长度字段不能为零,如果FIRST-STRING完全是空间,则可以计算它.
潜在的问题是:
MOVE FIRST-STRING TO OUTPUT-STRING
( 1 : length-field-you-define )
Run Code Online (Sandbox Code Playgroud)
因此,根据您的数据(如果它可能包含空格),您必须"保护"它.
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 : )
.
Run Code Online (Sandbox Code Playgroud)
如果使用长度为零的引用修改,则结果是未定义的,尽管它可能与编译器"一起工作".
具有STRING和可变长度字段的解决方案不会"失败",因为引用修改之外的编译器对零长度项感到满意.
但是,应采用相同的"保护"有两个原因:您将插入前导空白("分隔符"); 你会明白你的代码,所以人们不必问自己"当第一个字段为空时会发生什么"; 你会节省处理费用.
通过这种方式,您的程序也可以"更好地描述您的数据".除了"了解您的数据"作为准确程序设计的必要性之外,您的程序描述数据的次数越多,创建佣金或遗漏错误就越困难,理解就越容易,而且越容易理解.当发生变化时,数据结构发生变化.
您还可以使用WITH POINTER选项查看STRING.首先,MOVE FIRST-STRING到OUTPUT-STRING(它也会将OUTPUT-STRING中未使用的字节清除到空间).然后在length-field-you-define(对于插入空间)中添加一个,并在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
Run Code Online (Sandbox Code Playgroud)
如果您有大量数据,最快的方法是仅限reference-modidifcation建议.我对引用修改的看法是它倾向于混淆,因为人们倾向于以混淆(和不必要的)方式使用它.
我的偏好是最后一个,其中PROCEDURE DIVISION代码非常简单:你在第一个字段中找到数据的长度; 你只做三个简单的MOVE.
也许你可以尝试各自,以便更加了解未来情况的可能性.
我不知道这是否会对你有所帮助,但如果你想删除第一个字符串的尾随空格,你可以在查询字符串之前这样做:
INSPECT FUNCTION REVERSE(FIRST-STRING) TALLYING W-SPACES FOR LEADING SPACES
COMPUTE W-FIRST-STRING-LEN = LENGTH OF FIRST-STRING - W-SPACES
Run Code Online (Sandbox Code Playgroud)
FIRST-STRING(1:W-FIRST-STRING-LEN) 然后包含没有尾随空格的第一个字符串(JOHN SNOW)