如果您看到此消息,那么(几乎可以肯定)这是一个COBOL编程错误。大多数COBOL程序员都会犯这个愚蠢的错误,我也不例外。
问题是由我们通常初始化记录的方式引起的。让我们来看一个像这样的小程序:
identification division.
program-id.
mistake.
data division.
working-storage section.
* *** Input record, typically maintained on disk/tape somewhere.
01 dr-datarec.
03 dr-name pic x(20).
03 dr-amount pic s9(7)v99, comp-3.
* *** print record, sent to a line printer.
01 dt-detail.
03 dt-name pic x(20).
03 filler pic x.
03 dt-amount pic z,zzz,zz9.99.
procedure division.
move spaces to dr-datarec.
move "test" to dr-name.
move 100 to dr-amount.
move spaces to dt-detail.
move dr-name to dt-name.
move dr-amount to dt-amount.
display dt-detail.
stop run.
在此程序中,输入记录
dr-datarec
。通常它来自磁盘上的某个位置,但是对于此简单测试,它是手动创建的。
收到输入记录后,将执行计算,然后使用输出记录
dt-detail
。
问题是如何创建记录
dr-datarec
。注意如何移动空格以对其进行初始化。这是初始化记录的典型方法。
因此,PIC X的所有字段中都有空格。但是!所有COMP-3字段也都被初始化,但不为零。程序员必须确保为所有COMP-3字段生成了有效值。测试程序可以正确执行:
move spaces to dr-datarec.
move "test" to dr-name.
move 100 to dr-amount.
dr-amount
显然
,该字段中有100个。
./mistake
test 100.00
如果出现编码错误并且记录
dr-amount
未正确初始化怎么办?
那里仍然有ASCII空格。这是十六进制值20或二进制00100000。COMP
-3将数字存储为四位半字节,因此一个空格显示为20。如果您有9位数字(例如dr-amount),则需要10个存储半字节(9个半字节)代表数字,一个代表符号)或5个字节。
在其中移动空格
dr-datarec
将导致5个空格或十六进制值2020202020存储在此字段中,如果尝试使用未初始化的变量,它将被解释为2020 202.02。
如果注释掉初始化
dr-amount
,则可以强制执行此错误:
move spaces to dr-datarec.
move "test" to dr-name.
* move 100 to dr-amount.
现在,当启动程序时:
./mistake
test 2,020,202.02
为了解决此问题,COBOL 85引入了INITIALIZE动词。不用将空格移动到记录中,而是对其进行初始化,然后将空格移动到字母数字字段,将零移动到数字字段:
* move spaces to dr-datarec.
initialize dt-detail.
move "test" to dr-name.
* move 100 to dr-amount.
执行结果:
./mistake
test 0.00
因此,下一次您看到一位可怜的寡妇得到2,020,202.02美元的水电费时,您将确切知道发生了什么!