我正在家里编写一些代码,假设查找和识别错误是一个输入文件。我猜对了,但有两个小错误打击了我。不过主要的问题是这个。我必须制作一个将“3077.B22”标识为错误的代码,因为前 5 列假设是数字,但我当前的代码让它通过。不过,它会影响其他所有事情,因此我不得不相信它将句点视为小数点。这是我对这部分的担忧。
01 PART-NUMBER-CHECK.
05 P-N-NUM-1 PIC X(5).
05 P-N-LETTER PIC X.
05 P-N-NUM-2 PIC XX.
300-VALIDATE-PART-NUMBER.
MOVE 'NO' TO FIELD-ERROR-SWITCH
MOVE PART-NUMBER TO PART-NUMBER-CHECK
EVALUATE P-N-NUM-1
WHEN 00001 THRU 99999 CONTINUE
WHEN OTHER MOVE 'YES' TO FIELD-ERROR-SWITCH
END-EVALUATE
IF P-N-LETTER IS NUMERIC
MOVE 'YES' TO FIELD-ERROR-SWITCH
END-IF
IF P-N-LETTER IS ALPHABETIC-LOWER
MOVE 'YES' TO FIELD-ERROR-SWITCH
END-IF
IF P-N-NUM-2 IS ALPHABETIC
MOVE 'YES' TO FIELD-ERROR-SWITCH
END-IF
IF (P-N-NUM-2 > 00 AND < 69)
OR (P-N-NUM-2 >77 AND < 100)
CONTINUE
ELSE
MOVE 'YES' TO FIELD-ERROR-SWITCH
END-IF
IF FIELD-ERROR-SWITCH = 'YES'
MOVE 'YES' TO RECORD-ERROR-SWITCH
MOVE 'Part Number' TO FIELD-NAME
MOVE PART-NUMBER TO FIELD-VALUE
PERFORM 400-WRITE-DETAIL-LINE
END-IF.
Run Code Online (Sandbox Code Playgroud)
我的第二个问题是类似的,因为它将另一个字段中的 * 视为字母。下面是这段话:
340-VALIDATE-INITIAL.
MOVE 'NO' TO FIELD-ERROR-SWITCH
INSPECT INITIALS
TALLYING I-CHECK FOR ALL SPACES
IF I-CHECK > 0
MOVE 'YES' TO FIELD-ERROR-SWITCH
MOVE 0 TO I-CHECK
END-IF
IF INITIALS IS NUMERIC
MOVE 'YES' TO FIELD-ERROR-SWITCH
END-IF
IF FIELD-ERROR-SWITCH = 'YES'
MOVE 'YES' TO RECORD-ERROR-SWITCH
MOVE 'Initials' TO FIELD-NAME
MOVE INITIALS TO FIELD-VALUE
PERFORM 400-WRITE-DETAIL-LINE
END-IF.
Run Code Online (Sandbox Code Playgroud)
请帮忙,我一越过路上的这个小颠簸,我就完成了。
鉴于以下声明:
01 PART-NUMBER-CHECK.
05 P-N-NUM-1 PIC X(5).
05 P-N-LETTER PIC X.
05 P-N-NUM-2 PIC XX.
Run Code Online (Sandbox Code Playgroud)
和类似的东西:
MOVE 'NO' TO FIELD-ERROR-SWITCH
MOVE '3077.B22' TO PART-NUMBER-CHECK
EVALUATE P-N-NUM-1
WHEN 00001 THRU 99999 CONTINUE
WHEN OTHER MOVE 'YES' TO FIELD-ERROR-SWITCH
END-EVALUATE
Run Code Online (Sandbox Code Playgroud)
为什么不FIELD-ERROR-SWITCH
设置为“是”?PIC X
在应用范围测试之前,COBOL 将 00001 和 99999 转换为它们的等价物(这里的转换规则相当复杂,所以我不打算深入研究)。COBOL 在这里执行的实际测试大致相当于以下内容:
IF '00001' <= '3077.' AND '99999' >= '3077.'
Run Code Online (Sandbox Code Playgroud)
鉴于这些是字符串测试,条件为真,这意味着您可以绕过设置FIELD-ERROR-SWITCH
. THRU
在 COBOL 中使用范围测试非常有用,但需要谨慎。仅THRU
当您知道您有有效数据开始或正在进行单字符比较时才使用
。例如
05 TEST-CHAR PIC X.
88 IS-DIGIT VALUE '0' THRU '9'.
88 IS-LOWER-LETTER VALUE 'a' THRU 'i',
'j' THRU 'r',
's' THRU 'z'.
88 IS-UPPER-LETTER VALUE 'A' THRU 'I',
'J' THRU 'R',
'S' THRU 'Z'.
88 IS-SPACE VALUE SPACE.
Run Code Online (Sandbox Code Playgroud)
然后代码如下:
MOVE SOME-CHAR TO TEST-CHAR
EVALUATE TRUE
WHEN IS-DIGIT
DISPLAY 'IS A DIGIT'
WHEN IS-LOWER-LETTER OR IS-UPPER-LETTER
DISPLAY 'IS ALPHA'
WHEN IS-SPACE
DISPLAY 'IS A SPACE'
WHEN OTHER
DISPLAY 'IS A SOMETHING ELSE'
END-EVALUATE
Run Code Online (Sandbox Code Playgroud)
几乎是防弹的。为什么我将字母范围分成不同的组?查看 EBCDIC 整理序列,您会发现一些非字母字符出现在 'i' 和 'j' 之间,然后又出现在 'r' 和 's' 之间!哦,我多么喜欢 EBCDIC!
如何解决您的问题?像这样简单的事情:
IF P-N-NUM-1 IS NUMERIC
IF P-N-NUM-1 = ZERO
MOVE 'YES' TO FIELD-ERROR-SWITCH
END-IF
ELSE
MOVE 'YES' TO FIELD-ERROR-SWITCH
END-IF
Run Code Online (Sandbox Code Playgroud)
会做的伎俩。该NUMERIC
测试确保它P-N-NUM-1
仅由数字组成。该ZERO
测试确保它不为零。在这种情况下,NUMERIC
测试中排除了负数。NUMERIC
当被测试的项目被声明为PIC X
或时,句号/加号/减号不是PIC 9
。如果基本项目被声明为PIC S9(5) PACKED-DECIMAL
,那么一个领先的标志将通过NUMERIC
测试。COBOLNUMERIC
类测试需要一些研究才能完全理解。
重要提示:确保应该是数字的东西存储在声明为数字的基本项目中。我会尝试声明P-N-NUM-1
和
P-N-NUM-2
使用PIC 9
. 将未验证的数据移动到PART-NUMBER-CHECK
默认情况下PIC X
不会发生错误的位置,然后使用IF NUMERIC
测试验证基本数字数据项
。一旦你知道你有数字数据,那么你的范围测试(例如00001 THRU 99999
,大于/小于)不会让你误入歧途 - 就像这里发生的那样。
为什么在你的第二位代码中会出现一个“*”?您永远不会在非字母字符上设置错误,只会在数字上设置错误。为什么不尝试将您的NUMERIC
测试转换为NOT ALPHABETIC
测试?
看看有没有帮助!