句点算作数字吗 (COBOL)

发布于 2024-10-13 08:04:37 字数 1954 浏览 8 评论 0原文

我正在家里编写一些代码,假设查找和识别错误是一个输入文件。我的理解基本正确,但有两个小错误困扰着我。但主要问题是这个。我必须编写一个代码,将“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.

我的第二个问题是类似的,因为它在另一个字段中将 * 视为字母。 这是该段落:

   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.

请帮忙,一旦克服了路上的这个小颠簸,我就完成了。

I am working on a bit of code at home and that is suppose to find and identify errors is a input file. I got it just about right, but two little errors are hitting me. The major problem though is this. I have to make a code that identifies "3077.B22" as an error because the first 5 columns are suppose to be numeric, but my current code is letting it pass. It hits every thing else though so I have to believe that it is seeing the period as a decimal point. Here is what I got that concerns to this part.

   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.

My second problem is similar cause it is seeing an * in another field as a alphabetic.
Here is the paragraph to that:

   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.

Please help, I am done as soon as I get over this little bump in the road.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

断念 2024-10-20 08:04:37

给出以下声明:

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.

以及类似的内容:

   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

为什么 FIELD-ERROR-SWITCH 设置为“YES”? COBOL 转换
在应用之前将 00001 和 99999 转换为其等效的 PIC X
范围测试(这里的铸造规则相当复杂,所以我不打算
进入其中)。 COBOL 的实际测试在这里执行
大致相当于以下内容:

IF '00001' <= '3077.' AND '99999' >= '3077.'

鉴于这些是字符串测试,条件是
true,这意味着您绕过设置FIELD-ERROR-SWITCH。使用
COBOL 中的 THRU 范围测试非常有用,但需要小心。仅使用
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.

,像这样的代码

 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

几乎是防弹的。
为什么我将字母表范围分成不同的组?查看 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

就可以了。 NUMERIC 测试确保 PN-NUM-1 组成
仅由数字组成。 ZERO 测试确保它不为零。在这种情况下负数
被排除在 NUMERIC 测试中。当句号/加号/减号不是 NUMERIC
正在测试的项目声明为 PIC XPIC 9。如果基本项被声明为PIC S9(5) PACKED-DECIMAL,则前导符号将通过NUMERIC测试。 COBOL NUMERIC 类测试需要一些研究才能完全理解。

大提示:确保存储应该是数字的内容
在声明为数字的基本项中。我会尝试声明 PN-NUM-1
使用 PIC 9PN-NUM-2。将未经验证的数据移入默认情况下的 PART-NUMBER-CHECK
PIC X 因此不会发生错误,然后使用以下命令验证基本数字数据项
IF NUMERIC 测试。一旦你知道你有数字数据,那么你的范围测试(例如00001 THRU 99999
大于/小于)不会让你误入歧途 - 就像这里发生的那样。

为什么你的第二段代码中会出现一个“*”?你永远不会在非字母字符上设置错误,
仅在数字上。为什么不尝试将 NUMERIC 测试翻转为 NOT ALPHABETIC 测试呢?

看看是否有帮助!

Given the following declaration:

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.

and something like:

   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

Why isn't the FIELD-ERROR-SWITCH set to 'YES'? COBOL casts
00001 and 99999 into their PIC X equivalents before applying
the range tests (casting rules here are rather complicated so I'm not going to
get into it). The actual test COBOL performs here
is roughly equivalent to the following:

IF '00001' <= '3077.' AND '99999' >= '3077.'

Given that these are string tests the condition is
true, meaning that you bypass setting the FIELD-ERROR-SWITCH. Using
a THRU range test in COBOL is very useful but requires a bit of caution. Only use
THRU when you know you have valid data to begin with or are doing single character
comparisons. For example

 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.

Then code like:

 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

is pretty much bullet proof.
Why did I break the alphabet range up into distinct groups? Check out the EBCDIC
collating sequence and you will find that some non alphabet characters sneak
in between 'i' and 'j' then again between 'r' and 's'! Oh, how I love EBCDIC!

How to solve your problem? Something as simple as:

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

would do the trick. The NUMERIC test ensures that P-N-NUM-1 is composed
of only digits. The ZERO test ensures that it is not zero. In this case negative numbers
are excluded on the NUMERIC test. Period/plus/minus are not NUMERIC when the
item being tested is declared as PIC X or PIC 9. Had the elementary item been declared as PIC S9(5) PACKED-DECIMAL, then a leading sign would be pass the NUMERIC test. The COBOL NUMERIC class test takes a bit of study to fully understand.

Big hint: Ensure that things that are supposed to be numeric are stored
in elementary items that are declared as numeric. I would try declaring P-N-NUM-1 and
P-N-NUM-2 using PIC 9. Move un-validated data into PART-NUMBER-CHECK which by default
is PIC X so no errors occur, then validate elementary numeric data items using
IF NUMERIC tests. Once you know you have numeric data then your range tests (e.g. 00001 THRU 99999,
greater/less than) will not lead you astray - as happened here.

Why is an '*' sneaking through your second bit of code? You never set an error on non-alpha characters,
only on numerics. Why not try flipping your NUMERIC test into a NOT ALPHABETIC test?

See if that helps!

四叶草在未来唯美盛开 2024-10-20 08:04:37

您的方向是正确的,但是您的编译器支持 NumVal 函数吗?您可以这样做:

01 Part-Num 9(5).9(2)。

计算零件编号 = 函数 NumVal( 零件编号输入 )
例外情况
将 Part-Num-Not-Valid 设置为 true
终端计算

You are on the right track, but does your compiler support the NumVal function? You could do this:

01 Part-Num 9(5).9(2).

Compute Part-Num = Function NumVal( Part-Num-Input )
on exception
Set Part-Num-Not-Valid to true
End-Compute

风蛊 2024-10-20 08:04:37

自从我写上一篇 COBOL 以来已经很长时间了,而且我手头没有编译器,所以期望在代码中进行一些语法检查,但你会明白的......

01  PART-NUMBER-CHECK.  
   05 P-N-NUM-1                .  
      07 p-x-occ occurs 5      pic X.  
   05 P-N-NUM-1-N    redefines P-N-NUM-1.           .  
      07 p-n-occ occurs 5      pic 9.  
   05 P-N-LETTER               PIC X.  
   05 P-N-NUM-2                PIC XX.  

01 FIELD-ERROR-SWITCH pic x(3).   
   88 no-error value 'NO'.   

300-VALIDATE-PART-NUMBER.
   MOVE 'NO' TO FIELD-ERROR-SWITCH  
   MOVE PART-NUMBER TO PART-NUMBER-CHECK.  
   perform validate-p-n-occurs varying I from 1 to 5.  
   if no-error  
      IF ( P-N-LETTER IS NUMERIC or P-N-LETTER IS ALPHABETIC-LOWER or  
           P-N-NUM-2 IS ALPHABETIC)  
         MOVE 'YES' TO FIELD-ERROR-SWITCH  
      ELSE    
          IF (P-N-NUM-2 < 0) OR (P-N-NUM-20 > 68 AND < 79) OR (P-N-NUM-2 >99)  
             MOVE 'YES' TO FIELD-ERROR-SWITCH  
          END-IF  
      END-IF
   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.  

validate-p-n-occurs.  
   IF p-x-occ(I) is not NUMERIC or (p-n-occ(I) < 0 or  > 10)
         MOVE 'YES' TO FIELD-ERROR-SWITCH  
   END-IF.       

A long time since I wrote my last COBOL, and I don't have a compiler at hand, so expect some sintax checks in the code, but you'll get the idea ...

01  PART-NUMBER-CHECK.  
   05 P-N-NUM-1                .  
      07 p-x-occ occurs 5      pic X.  
   05 P-N-NUM-1-N    redefines P-N-NUM-1.           .  
      07 p-n-occ occurs 5      pic 9.  
   05 P-N-LETTER               PIC X.  
   05 P-N-NUM-2                PIC XX.  

01 FIELD-ERROR-SWITCH pic x(3).   
   88 no-error value 'NO'.   

300-VALIDATE-PART-NUMBER.
   MOVE 'NO' TO FIELD-ERROR-SWITCH  
   MOVE PART-NUMBER TO PART-NUMBER-CHECK.  
   perform validate-p-n-occurs varying I from 1 to 5.  
   if no-error  
      IF ( P-N-LETTER IS NUMERIC or P-N-LETTER IS ALPHABETIC-LOWER or  
           P-N-NUM-2 IS ALPHABETIC)  
         MOVE 'YES' TO FIELD-ERROR-SWITCH  
      ELSE    
          IF (P-N-NUM-2 < 0) OR (P-N-NUM-20 > 68 AND < 79) OR (P-N-NUM-2 >99)  
             MOVE 'YES' TO FIELD-ERROR-SWITCH  
          END-IF  
      END-IF
   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.  

validate-p-n-occurs.  
   IF p-x-occ(I) is not NUMERIC or (p-n-occ(I) < 0 or  > 10)
         MOVE 'YES' TO FIELD-ERROR-SWITCH  
   END-IF.       
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文