首先,您为什么认为将 400 字节字段移动到 2 字节字段可能有用?您将获得“截断”的“一定数量(!)”(并且截断的数量是确定的,为 398 字节)。你知道400 字节的哪一部分会被截断吗?我猜不会。
对于字母数字“发送”项目(您拥有的),使用的(最大)字节数是数字字段中的最大字节数(18/31,取决于编译器/编译器选项)。这些字节取自字母数字字段的右侧。
因此,您已将最右边的18/31 位移动到两位数接收字段。您已经解释过您有“1”和 399 个空格,因此您已将 18/31 个空格移动到您的两位数字字段中。
您的数字字段是“无符号”(PIC 9(2) 不是 PIC S9(2) 或带有 SIGN SEPARATE)。对于无符号字段(即“无操作符号”的字段),COBOL 编译器应生成代码以确保该字段不包含符号。
此代码会将 PIC 9(2) 中最右边的空间变成“0”,因为 ASCII 空间是 X'20',EBCDIC 空间是 X'40'。“符号”嵌入在 USAGE DISPLAY 数字字段的最右边字节中,并且在 MOVE 期间除了符号之外没有其他数据发生变化。X'2n' 或 X'4n' 的 2 或 4 不考虑其值,被“无符号”(缺少“操作符号”)的位模式消除。一个“无符号”后跟一个数字(即空格中剩下的“0”)显然会显示为零。
现在,您为 400 字节字段显示一个“1”,为您的两字节数字显示一个 0。
我要做的是:
DISPLAY
">"
the-first-field-name
"<"
">"
the-second-field-name
"<"
...
或者
DISPLAY
">"
the-first-field-name
"<"
DISPLAY
">"
the-second-field-name
"<"
...
如果你这样做了,你应该会发现 1 后跟 399 个空格作为你的第一个字段(正如你所期望的)和空格后跟零作为你的第二个字段,这是你没想到的。
如果您想具体查看此操作:
FOO PIC X(400) JUST RIGHT.
MOVE "1" TO FOO
MOVE FOO TO BAR
DISPLAY
">"
FOO
"<"
DISPLAY
">"
BAR
"<"
你应该看到你“几乎”期望的东西。您可能还需要前导零(级别编号 05 是一个示例,您使用的任何级别编号都可以使用)。
05 BAR PIC 99.
05 FILLER REDEFINES BAR.
10 BAR-FIRST-BYTE PIC X.
88 BAR-FIRST-BYTE-SPACE VALUE SPACE.
10 FILLER PIC X.
...
IF BAR-FIRST-BYTE-SPACE
MOVE ZERO TO BAR-FIRST-BYTE
END-IF
根据您的编译器以及它与 ANSI 标准(以及哪个 ANSI 标准)的接近程度,您的结果可能会有所不同(如果是这样,请尝试获得更好的编译器),但是:
不要将长度超过数字的最大值的字母数字移动到数字;
请注意,在 MOVE alpha-numeric to numeric中,实际上首先移动的是字母-数字的最右边的字节;
“无符号”数字应该/必须始终保持无符号;
始终检查编译器诊断并更正代码,以便不产生诊断(如果可能);在显示示例时,显示计算机产生的实际
结果
非常重要,而不是人类解释的结果。“0”不等于“0”不等于“0”。
编辑:看看 TS 的其他问题,我认为 Enterprise COBOL 是一个安全的选择。此消息将由编译器发出:
IGYPG3112-W 字母数字或国家发送字段“FOO”超过 18 位。最右边的 18 个字符被用作发送者。
请注意,使用编译器选项 ARITH(EXTEND) 时,“18 位”将是“31 位”。
尽管它是一个低级的“W”,它只给出一个返回码 4,但不费心去阅读它不是一个好习惯,如果你读过它,你就不需要问这个问题——尽管也许你会仍然不知道你是如何以“0”结束的,但那是另一回事。