为小于指定长度的PIC子句分配值

时间:2013-10-23 08:36:13

标签: cobol mainframe

我是COBOL的初学者,我想知道如果我做了类似以下的事情会发生什么:
(我知道下面的代码不是可运行的cobol,例如它就在那里)

foo pic x(5)
accept foo

并且用户键入一个只有3个字符的字符串(例如是) foo的价值只是“是”吗?或者它会填充创建时指定的全部5个字符(例如:“(space)(space)yes”或“yes(space)(space)”,还是其他的东西?

谢谢!

这是我的代码

000100        IDENTIFICATION DIVISION.                           
000200       *--------------------                               
000300        PROGRAM-ID. ZIPCODES.                              
000400       *--------------------                               
000500        ENVIRONMENT DIVISION.                              
000600       *--------------------                               
000700        CONFIGURATION SECTION.                             
000800        INPUT-OUTPUT SECTION.                              
000900        FILE-CONTROL.                                      
001000            SELECT PRT ASSIGN TO UT-S-PRTAREA.             
001100                                                           
001200        DATA DIVISION.                                     
001300       *-------------                                      
001400        FILE SECTION.                                      
001500        FD  PRT                                            
001600            RECORD CONTAINS 80 CHARACTERS                  
001700            DATA RECORD IS LINE-PRT.
001800        01  LINE-PRT              PIC X(80).                
001900                                                            
002000        WORKING-STORAGE SECTION.                            
002100       *-----------------------                             
002200                 EXEC SQL INCLUDE SQLCA  END-EXEC.          
002300                                                            
002310        01 done.                                           
002320           02 donevar            PIC x(5) VALUE 'done '.    
002400        01 ZIP-RECORD.                                      
002500           02 ZIP                PIC X(5).                  
002600           02 ZCITY              PIC X(20).                 
002700           02 ZSTATE             PIC X(2).                  
002800           02 ZLOCATION          PIC X(35).                 
002900                                                            
003000        01 H1.                                              
003100           02 COLUMN-1           PIC X(8) VALUE 'Zip-Code'. 
003200           02 FILLER             PIC X(2).                  
003300           02 COLUMN-2           PIC X(5) VALUE 'State'.
003400           02 FILLER             PIC X(2).                       
003500           02 COLUMN-3           PIC X(4) VALUE 'City'.          
003600           02 FILLER             PIC X(16).                      
003700           02 COLUMN-4           PIC X(14) VALUE 'Location Text'.
003800           02 FILLER             PIC X(29).                      
003900                                                                 
004000        01 L1.                                                   
004100           02 ZIP-L1             PIC X(5).                       
004200           02 FILLER             PIC X(5).                       
004300           02 STATE-L1           PIC X(2).                       
004400           02 FILLER             PIC X(5).                       
004500           02 CITY-L1            PIC X(20).                      
004600           02 LOCTXT-L1          PIC X(35).                      
004700           02 FILLER             PIC X(28).                      
004800                                                                 
004900        PROCEDURE DIVISION.                                      
005000       *------------------                                       
005100        BEGIN.
 005200                 OPEN OUTPUT PRT.                                
 005220                 PERFORM ZIP-LOOKUP UNTIL ZIP = done.            
 005600        PROG-END.                                                
 005700                 CLOSE PRT.                                      
 005800                 GOBACK.                                         
 005900       *****************************************************     
 006000       * zip code lookup                                   *     
 006100       *****************************************************     
 006200        ZIP-LOOKUP.                                              
 006300                 DISPLAY 'enter 5 digit zip code'                
 006400                 ACCEPT ZIP                                      
 006500                 EXEC SQL                                        
 006600                  SELECT * INTO :ZIP-RECORD FROM ZBANK.ZIPCODE   
 006700                  WHERE ZIP = :ZIP                               
 006800                 END-EXEC.                                       
 006801                 PERFORM PRINT-H1.                               
 006802                 PERFORM PRINT-L1.                               
 006900        PRINT-H1.
007000                 MOVE H1 TO LINE-PRT                     
007100                 WRITE LINE-PRT.                         
007200        PRINT-L1.                                        
007300                 MOVE  ZIP          TO  ZIP-L1           
007400                 MOVE  ZSTATE       TO  STATE-L1         
007500                 MOVE  ZCITY        TO  CITY-L1          
007510                 STRING ZSTATE DELIMITED BY " ",", ",    
007520                 ZCITY DELIMITED BY SIZE INTO LOCTXT-L1  
007700                 MOVE  L1 TO LINE-PRT                    
007800                 WRITE LINE-PRT.

我正在尝试在zcity之前编写zstate,并且只要输入没有“完成”就让它继续询问邮政编码

1 个答案:

答案 0 :(得分:4)

输入的前5个字符将移至FOO。如果输入的字符少于5个,则它们将被放置在FOO的左手位置,其余字符(右侧)将填充空格。如果用户输入超过5个字符,则仅移动前5个字符。

因此,如果用户键入“是”,则使用您的示例,然后FOO将包含“是 bb

最好的办法就是试试吧!

编辑以回应更新的问题... 我认为你的问题是终止循环所需的条件是在循环体的开头设置的 不是最后的。以下是一些常用的技术来解决这个问题:

预循环阅读

          DISPLAY 'Enter a 5 digit zip code'
          ACCEPT ZIP
          PERFORM ZIP-LOOKUP UNTIL ZIP = done.
          ...
          ...
      ZIP-LOOKUP.
          EXEC SQL                                        
            SELECT * INTO :ZIP-RECORD FROM ZBANK.ZIPCODE   
            WHERE ZIP = :ZIP                               
          END-EXEC.                                       
          PERFORM PRINT-H1.                               
          PERFORM PRINT-L1.
     *    Now get next zip code or 'done'                    
          DISPLAY 'Enter a 5 digit zip code'
          ACCEPT ZIP
          .

防止在循环中设置终止条件

          PERFORM ZIP-LOOKUP UNTIL ZIP = done.
          ...
          ...
      ZIP-LOOKUP.
          DISPLAY 'Enter a 5 digit zip code'
          ACCEPT ZIP
          IF ZIP NOT = DONE
             EXEC SQL                                        
               SELECT * INTO :ZIP-RECORD FROM ZBANK.ZIPCODE   
               WHERE ZIP = :ZIP                               
             END-EXEC                                      
            PERFORM PRINT-H1                               
            PERFORM PRINT-L1
          END-IF
          .

上述任一项都可以解决您的问题。但是,我建议尝试更新您的编码样式以包含 COBOL-85构建体。上面的第一个例子可能编码如下:

          DISPLAY 'Enter a 5 digit zip code'
          ACCEPT ZIP
          PERFORM UNTIL ZIP = done
             EXEC SQL                                        
                  SELECT * INTO :ZIP-RECORD FROM ZBANK.ZIPCODE   
             WHERE ZIP = :ZIP                               
             END-EXEC                                       
             PERFORM PRINT-H1                              
             PERFORM PRINT-L1
             DISPLAY 'Enter a 5 digit zip code'
             ACCEPT ZIP
          END-PERFORM
          .

ZIP-LOOKUP段落已列入PERFORM语句。对于简短的代码部分,我发现这种风格更多 可读。 还要注意单句段落(段落末尾只有一个句点)。使用COBOL-85示波器终结器时(例如END-xxx) 每个段落需要多个句子消失 - 实际上 - 应该避免它们。

您可以使用的另一个COBOL构造是88 LEVEL。您可以按如下方式使用它:

        01 ZIP-RECORD.                                      
           02 ZIP                PIC X(5). 
              88 DONE            VALUE 'done  '.
        ...
        ...

您根本不再需要donevar。替换原来的测试:

                 
        IF ZIP = DONE

使用:

                 
        IF DONE

只要变量ZIP包含值“done bb ”,上述情况就会成立。一个优点 这样做(除了保存一个变量声明)是可以分配一个88 LEVEL名称 几个值,如:

        01 ZIP-RECORD.                                      
           02 ZIP                PIC X(5). 
              88 DONE            VALUE 'done  ',
                                       'quit  ',
                                       'stop  '.

当用户输入donequitstop中的任何一个时,88级别名称DONE的评估结果为真。

最后,我认为这只是程序的一个框架,完成的版本将检查I / O错误,错误的SQL代码 并进行基本的邮政编码验证。如果没有,你可能会遇到很多麻烦。

COBOL参考资料

不幸的是,很少有学习COBOL的最新资源。但是,其中之一 我推荐的书是Advanced Cobol 3rd Edition by DeWard Brown。 本书提供了许多关于COBOL程序开发的示例和解释。它还确定是否 构造很少使用,过时或必不可少。这很有用,因为您应该使用现代COBOL开发新代码 编程技术(我继续看到很多新的COBOL使用前COBOL 85编码实践开发 - 这太可怕了。)

开源 指南是OpenCOBOL Programmers Guide。这个目标是OpenCOBOL但是 其中大部分适用于任何风味的COBOL。

最后,有几个供应商指南和手册,其中许多可在互联网上找到。对于 示例Enterprise COBOL for z/OS Language ReferenceEnterprise COBOL for z/OS Programming guide是 免费提供。微焦点COBOL 指南也可用。搜索任何你会发现......