COBOL数据验证是否为大写字母?

4
我在大学的第二个学期,正在学习“高级COBOL”,我们刚拿到一项任务,需要为不同的数据编写一些验证程序。除了一个小的验证程序外,我已经完成了所有的工作。其中有一个名为“PART-NUMBER”的字段,长度为8字节。前5列必须是数字,第6列必须是大写字母,最后2列必须在01-68或78-99的范围内。我唯一的问题是如何验证第6列是大写字母。这是我正在使用的代码:从工作存储器:

01 DETAIL-LINE.                                         
05 PART-NUMBER.                                     
    10 PART-FIRST-FIVE-DL        PIC X(5).          
    10 PART-LETTER-DL            PIC X.             
        88 CAPITAL-LETTER        VALUE 'A' THRU 'Z'.
    10 PART-LAST-TWO-DL          PIC XX.

From 300-VALIDATE-PART-NUMBER

EVALUATE PART-LETTER-DL ALPHABETIC               
   WHEN TRUE EVALUATE CAPITAL-LETTER               
      WHEN FALSE MOVE 'YES' TO RECORD-ERROR-SWITCH
      MOVE 'PART NUMBER' TO FIELD-NAME            
      MOVE PART-NO-IN TO FIELD-VALUE              
      MOVE 'YES' TO PART-NO-ERROR                 
   END-EVALUATE                                    
   WHEN FALSE MOVE 'YES' TO RECORD-ERROR-SWITCH    
   MOVE 'PART NUMBER' TO FIELD-NAME                
   MOVE PART-NO-IN TO FIELD-VALUE                  
   MOVE 'YES' TO PART-NO-ERROR                     
END-EVALUATE 

我知道我现在可能没有高效的做法,但是现在我只是需要让它能够工作。我已经读完了这本书中有关数据验证的整章内容,但是由于时间很紧(程序明天就要交),所以老师不在场。如果你能提供任何帮助,我将不胜感激。我真的不知道我应该如何验证大写字母。目前我正在使用的方法是:如果在零件号的第六列中出现A或Z之外的任何字符,则会报错。


去年有人遇到了同样的问题,但没有像你一样走得这么远 - 数据验证(COBOL) - 但那里的答案很好。 - sarnold
是的,实际上在我发帖之前我就找到了那个,但我完全不理解。我认为它远远超出了我们目前所学的范围。 - Shane
4个回答

4

我认为你的代码没有根本性的问题。我把它放到一个驱动程序中,编译并运行了它。我得到了预期的结果:只有当PART-NUMBER的第6个字符不是大写字母时才报错。

你的COBOL编码风格与我习惯看到的非常不同(并不是错误,只是不同)。

大多数资深的COBOL程序员会这样编码:

    IF PART-LETTER-DL IS ALPHABETIC AND
       CAPITAL-LETTER
       CONTINUE
    ELSE
       MOVE 'PART NUMBER' TO FIELD-NAME            
       MOVE PART-NO-IN TO FIELD-VALUE              
       MOVE 'YES' TO PART-NO-ERROR
    END-IF
IF语句同时应用了您的两个编辑条件,如果两个条件都通过(CONTINUE),则什么也不做;否则会报错(ELSE部分)。上述代码与您的示例代码实现的功能基本相同,只是使用了IF而非EVALUATE
我给您的代码打满分,因为它使用了88级范围(THRU)来测试ALPHABETIC和大写字母。许多程序员只使用88级范围,并默认“A” THRU “Z”只包含字母字符,但在某些环境中(特别是EBCDIC字符集),这是完全错误的。
附言:我看到你们一定有跟Kimmy一样的老师!

1

对于大写字母,您可以测试 ALPHABETIC-UPPER 条件:

IF PART-LETTER-DL NOT EQUAL SPACE AND PART-LETTER-DL IS ALPHABETIC-UPPER
 ...
END-IF.

也可以使用 ALPHABETIC-LOWER,但请记住,空格被视为字母,因此如果您只想要大写字母,则需要测试空格。


1
你需要关注的一件事是“Value 'A' thru 'Z'”。它只能在ASCII机器上工作。
如果你实际编写了“Value 'A','B','C',... 'Z'”,它将在所有平台上工作。

问题中提供的代码在我所知道的所有平台上都能正常工作。只有当字符集编码在同一值范围内混合大小写字母时,它才会失败。这在ASCII、EBCDIC或Unicode字符集中不会发生,因此我认为所采用的方法几乎是完美的。然而,如果没有ALPHABETIC测试,'A' THRU 'Z'将在EBCDIC中失败,因为非字母字符出现在'A'到'Z'的值范围内。 - NealB
"A"到"Z"将允许非字符作为有效字符...在EBCDIC上。 - Joe Zitzelberger
...但是字母表不行 - 将这两个测试结合起来可以解决这个问题。 - NealB
代码本身是正确的,但数据项仍然存在被误解的可能性。 - Joe Zitzelberger

0

对于EBCDIC,请删除字母测试并只使用88:

88 CAPITAL-LETTER        VALUE 'A' THRU 'I'
                               'J' THRU 'R'
                               'S' THRU 'Z'.

指定单个字母可以工作,但需要进行26次比较!上述方法只需要3次比较。使用字母表加上"A"到"Z"只需要2次比较,但可能会带来某些内置的混淆(空格是字母,而"THRU"包括范围为X'C1'到X'E9'的不可打印数字)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接