2015-02-09 129 views
0

编写我的程序,但我无法根据需要得到正确的输出 下面是我的代码和我的输入与输出。输出错误

此外,我的程序程序是否有意义,或者我应该修改它,这看起来很有道理,但看了不同的书后我不再确定了。

FD INPUT-FILE. 
    01 INPUT-RECORD. 
     05 EXCUSE-NUMBER      PIC 9(02). 
      88 VALID-EXCUSE     VALUE 1 THRU 10. 
     05 FILLER       PIC X(03). 
     05 NUMBER-TIMES-USED     PIC 9(02). 
     05 FILLER       PIC X(73). 

    FD REPORT-FILE. 
    01 REPORT-RECORD       PIC X(80). 

    FD ERROR-FILE. 
    01 ERROR-RECORD       PIC X(80). 

    WORKING-STORAGE SECTION. 
    ****************************************************************** 
    * DEFINES PROCESSINGVARIABLES AND OUTPUT LINES     * 
    ****************************************************************** 
    01 WS-AREA. 
     05 WS-IF-STATUS      PIC X(02). 
     05 WS-OF-STATUS      PIC X(02). 
     05 WS-EF-STATUS      PIC X(02). 
     05 WS-END-OF-FILE     PIC X(01) VALUE "N". 
      88 AT-WS-END-OF-FILE      VALUE "Y". 
     05 WS-INVALID-RECORD     PIC X(01) VALUE "N". 
     05 WS-LINE-NUMBER     PIC 9(03) VALUE 0. 
     05 WS-MOST-USED-EXCUSE    PIC 9(02) VALUE 0. 
     05 WS-EXCUSE       PIC 9(02) VALUE 0. 
     05 WS-EXCUSE-TOTAL     PIC 9(04). 

    01 BLANK-LINE. 
     05         PIC X(80). 

    ****************************************************************** 
    * (THIS IS WHERE THE HEADING ON THE PRINT OUT SHEET GOES)  * 
    ****************************************************************** 

    01 HEADING-LINE-1. 
     05 FILLER       PIC X(14) VALUE SPACES. 
     05 FILLER       PIC X(37) 
       VALUE "TEN MOST OUTRAGEOUS HOME-WORK EXCUSES". 

    01 HEADING-LINE-2. 
     05 FILLER       PIC X(11). 
     05 FILLER       PIC X(06) VALUE "RECORD". 
     05 FILLER       PIC X(08). 
     05 FILLER       PIC X(05) VALUE "IMAGE". 

    ****************************************************************** 
    * DETAIL-LINE COMMENTS.           * 
    * on the detail line we are writing out the Data information  * 
    * in particular, when we write out the line-number, error  * 
    * excuse number, excuses used, and how many times used   * 
    * Detail summary will be reported out       * 
    * Stars will be Display underneath bad data.      * 
    ***************************************************************** 
    01 DETAIL-LINE. 
     05 FILLER       PIC X(03). 
     05 DL-EXCUSE-NUMBER     PIC 9(02). 
     05 FILLER       PIC X(03). 
     05 DL-EXCUSE-USED     PIC X(51). 
     05 FILLER       PIC X(03). 
     05 DL-AMOUNT-USED     PIC ZZ9. 

    01 DETAIL-LINE-ERROR-1. 
     05 FILLER       PIC X(08) VALUE SPACES. 
     05 DLE-LINE-NUMBER     PIC ZZ9. 
     05 FILLER       PIC X(09) VALUE SPACES. 
     05 DLE-ERROR      PIC X(16). 

    01 DETAIL-LINE-ERROR-2. 
     05 FILLER       PIC X(20) VALUE SPACES. 
     05 DLE-EXCUSE-NUMBER    PIC X(02) VALUE SPACES. 
     05 FILLER       PIC X(03) VALUE SPACES. 
     05 DLE-EXCUSE      PIC X(02) VALUE SPACES. 

    01 DETAIL-TOTAL. 
     05 FILLER       PIC X(41) VALUE SPACES. 
     05 FILLER       PIC X(20) 
       VALUE "TOTAL EXCUSES USED =". 
     05 DT-TOTAL       PIC ZZZ9 VALUE ZERO. 

    01 DETAIL-TOTAL-MOST-USED. 
     05 FILLER       PIC X(34) VALUE SPACES. 
     05 FILLER       PIC X(27) 
       VALUE "EXCUSE USE THE MOST TIMES =". 
     05 DTMU-HIGH      PIC ZZZ9. 

    ****************************************************************** 
    * This is where we hard code the excuses used with the table  * 
    * from the input file.           * 
    ****************************************************************** 
    01 TABLE-EXCUSES-1. 
     05 PIC X(51) 
     VALUE "JOHN CONVINCE ME TO CONVERT TO LINUX". 
     05 PIC X(51) 
     VALUE "BEACUSE OF SECURITY REASON I CAN'T CONFIRM NOR DENY". 
     05 PIC X(51) 
     VALUE "BECAUSE THE HOSPITAL DOESN'T HAVE WIFI'". 
     05 PIC X(51) 
     VALUE "AFTER INSTALLING LINUX MY SYSTEM CRASHED". 
     05 PIC X(51) 
     VALUE "WHAT WAS THE QUESTION AGAIN". 
     05 PIC X(51) 
     VALUE "ARE YOU SURE, I REMEBER TURNING IT IN". 
     05 PIC X(51) 
     VALUE "I'M INVOKING MY 5TH AMENDMENT RIGHT". 
     05 PIC X(51) 
     VALUE "LINUX MADE ME CRAZY I THREW MY COMPUTER". 
     05 PIC X(51) 
     VALUE "SOMEONE STOLED MY BACKPACK". 
     05 PIC X(51) 
     VALUE "BEACUSE OF SECURITY REASON I CAN'T CONFIRM NOR DENY". 

    01 TABLE-EXCUSES-2 REDEFINES TABLE-EXCUSES-1. 
     05 TEN-EXCUSES OCCURS 10 TIMES  PIC X(51). 

    01 TABLE-EXCUSES-COUNTER. 
     05 TABLE-EXCUSES-COUNT OCCURS 10 TIMES PIC 9(03). 


    PROCEDURE DIVISION. 
    ****************************************************************** 
    * Finally - where the real work gets done      * 
    * it is divided into paragraphs (or modules) generally called * 
    * from the main controlling module (here 1000-MAIN-CONTROL).  * 
    * 1000-Main be the control module,        * 
    * 2000-Initialize            * 
    * 3000-Process             * 
    * 4000-Finish             * 
    ****************************************************************** 
    1000-MAIN. 
     OPEN INPUT INPUT-FILE 
      OUTPUT REPORT-FILE, ERROR-FILE 

     PERFORM 2000-INITIALIZE 

     PERFORM UNTIL AT-WS-END-OF-FILE 

      READ INPUT-FILE 
       AT END MOVE "Y" TO WS-END-OF-FILE 
       NOT AT END PERFORM 3000-PROCESS 
      END-READ 
     END-PERFORM 


     PERFORM 4000-FINISH 
      VARYING WS-EXCUSE 
      FROM 1 BY 1 
      UNTIL WS-EXCUSE > 10 

     MOVE WS-MOST-USED-EXCUSE TO DTMU-HIGH 
     MOVE WS-EXCUSE-TOTAL TO DT-TOTAL 
     WRITE REPORT-RECORD FROM BLANK-LINE 
     WRITE REPORT-RECORD FROM DETAIL-TOTAL 
     WRITE REPORT-RECORD FROM BLANK-LINE 
     WRITE REPORT-RECORD FROM DETAIL-TOTAL-MOST-USED. 

     CLOSE INPUT-FILE REPORT-FILE ERROR-FILE 
     STOP RUN. 

    2000-INITIALIZE. 
     INITIALIZE WS-EXCUSE 
     INITIALIZE TABLE-EXCUSES-COUNTER 
     WRITE ERROR-RECORD FROM HEADING-LINE-2 
     WRITE ERROR-RECORD FROM BLANK-LINE 
     WRITE REPORT-RECORD FROM HEADING-LINE-1 
     WRITE REPORT-RECORD FROM BLANK-LINE. 

    3000-PROCESS. 
     MOVE "N" TO WS-INVALID-RECORD 
     ADD 1 TO WS-LINE-NUMBER 

     IF NOT VALID-EXCUSE 
     MOVE INPUT-RECORD TO DLE-ERROR 
     MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
     MOVE "Y" TO WS-INVALID-RECORD 
     MOVE ALL "*" TO DLE-EXCUSE-NUMBER 

     END-IF. 

     IF WS-INVALID-RECORD = "N" 
     INSPECT EXCUSE-NUMBER REPLACING LEADING SPACES BY ZERO 
     IF EXCUSE-NUMBER IS NUMERIC 
      ADD EXCUSE-NUMBER TO TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) 
     IF TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) > 
      WS-MOST-USED-EXCUSE 
     MOVE TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) 
              TO WS-MOST-USED-EXCUSE 
     END-IF 

      ADD NUMBER-TIMES-USED TO WS-EXCUSE-TOTAL 

     ELSE 

     MOVE "Y" TO WS-INVALID-RECORD 
     MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
     MOVE INPUT-RECORD TO DLE-ERROR 
     MOVE ALL "*" TO DLE-EXCUSE 

      END-IF 

     END-IF. 

     IF WS-INVALID-RECORD = "Y" 
     WRITE ERROR-RECORD FROM DETAIL-LINE-ERROR-1 
     WRITE ERROR-RECORD FROM DETAIL-LINE-ERROR-2 
     MOVE SPACES TO DETAIL-LINE-ERROR-1 
     MOVE SPACES TO DETAIL-LINE-ERROR-2 

     END-IF. 

    4000-FINISH. 
     MOVE WS-EXCUSE TO DL-EXCUSE-NUMBER 
     MOVE TEN-EXCUSES(WS-EXCUSE) TO DL-EXCUSE-USED 
     MOVE TABLE-EXCUSES-COUNT(WS-EXCUSE) TO DL-AMOUNT-USED 
     WRITE REPORT-RECORD FROM DETAIL-LINE 
     WRITE REPORT-RECORD FROM BLANK-LINE 
     MOVE SPACES TO DETAIL-LINE. 

我的输出结果如下,然后按照应该的结果。

RECORD  IMAGE 

     3   0r4000700  03 
        ** 
    12   125999999  12 
       ** 
    21   125000899  21 
       ** 
    23   A01001111  23 
       **     

应该是:

RECORD  IMAGE 

     3   0r4000700  03 
       ** 
     6   074000Q00  06 
        ** 
    12   125999999  12 
       ** 
    21   125000899  21 
       ** 
    23   A01001111  23 
       ** 
+0

所以 - 你的输入文件在哪里产生这个输出? – Magoo 2015-02-09 05:14:33

+0

善良没有。请把它换回来。我并不担心接受,而是被拿走。现在你也已经对布鲁斯做过了。对布鲁斯的接受是比较深思熟虑的。下次更要小心。 – 2015-02-10 07:37:31

回答

2

你有两个问题,这是造成记录编号三到不正确的错误,并记录排名第六的完全不出现错误出现。

我缩进了你的代码,让你更好地看看发生了什么。

像往常一样,编译器不关心,不记录缩进,所以它是为人类。这样做。缩进。通常你会看到一些你自己的错误。

IF NOT VALID-EXCUSE 
     MOVE INPUT-RECORD TO DLE-ERROR 
     MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
     MOVE "Y" TO WS-INVALID-RECORD 
     MOVE ALL "*" TO DLE-EXCUSE-NUMBER 
    END-IF 

    IF WS-INVALID-RECORD = "N" 
     INSPECT EXCUSE-NUMBER REPLACING LEADING SPACES BY ZERO 
     IF EXCUSE-NUMBER IS NUMERIC 
      ADD EXCUSE-NUMBER TO TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) 
      IF TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) > 
       WS-MOST-USED-EXCUSE 
       MOVE TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) 
             TO WS-MOST-USED-EXCUSE 
      END-IF 
      ADD NUMBER-TIMES-USED TO WS-EXCUSE-TOTAL 
     ELSE 
      MOVE "Y" TO WS-INVALID-RECORD 
      MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
      MOVE INPUT-RECORD TO DLE-ERROR 
      MOVE ALL "*" TO DLE-EXCUSE 
     END-IF 
    END-IF 

如果我们先记录三条。在88

你的范围测试(很好用88S,做更多)就是这样的,在十六进制:

X'3031' through X'3130'. 

这将工作,如果该领域已经知道是数字,但除此之外,因为数字出现在以ASCII形式出现的字母之前,所以你不想要的东西会被视为“有效”。 12的值因为大于10(X'3130')而被拒绝。任何以零开头的字母都将被视为有效,任何控制代码或任何其他值恰好适合大量非数字值。

正如Bruce Martin所指出的那样,在应用该测试之前,您需要知道该字段是NUMERIC。

IF EXCUSE-NUMBER NUMERIC 
    AND NOT VALID-EXCUSE 
     MOVE INPUT-RECORD TO DLE-ERROR 
     MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
     MOVE "Y" TO WS-INVALID-RECORD 
     MOVE ALL "*" TO DLE-EXCUSE-NUMBER 
    END-IF 

这对人类来说变得有点难以阅读(编译器不介意)。布鲁斯的建议,为了简化(积极检查和CONTINUEELSE赶上坏数据)是一个很好的一个:

IF (EXCUSE-NUMBER NUMERIC) 
    AND (VALID-EXCUSE) 
     [all the good data goes here] 
     CONTINUE 
    ELSE 
     [leaving all the bad data here, ie both not numeric and 
     numeric but not in range] 
     MOVE INPUT-RECORD TO DLE-ERROR 
     MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
     MOVE "Y" TO WS-INVALID-RECORD 
     MOVE ALL "*" TO DLE-EXCUSE-NUMBER 
    END-IF 

注意:您所需要的数字型加范围内,当您验证数据。一旦良好的数据在您的系统中,范围检查将“按预期”工作,因为不会有干扰非数字数据来损害情节。

您还可以得到为借口-NUMBER做两种类型的错误一次,简化了以下IF。

如果您可以在任何一个字段中都有空白,您需要在之前处理任何检查。您不需要使用INSPECT

用两个字节场只是REDEFINES这样你就可以给整个领域的字母和数字的名称,第一个字节的名称。把88放在具有空间价值的人身上。如果88是真的,设置为零(整场或字节,两个测试):

IF 88-level 
    MOVE ZERO TO name-you've-given 
END-IF 

到目前为止,记三分已经被视为有效。现在它进入你的nested-IF。它EXCUSE-NUMBER不是NUMERIC,因此命中ELSE,在那里你为第二个字段编码。因为你没有缩进,所以这个模糊了。

记录三被拒绝“意外”。

在嵌套-IF,你的意思是检查NUMBER-TIMES-USED对于数字。

这就解释了为什么纪录6不出现错误,因为它的唯一的过错就是NUMBER-TIMES使用的不是数字的,你的程序目前并没有注意到。

你还错误地添加借口-NUMBER而不是

NUMBER-TIMES使用。

IF WS-INVALID-RECORD = "N" 
    [stuff for leading space] 
    IF NUMBER-TIMES-USED IS NUMERIC 
     ADD NUMBER-TIMES-USED TO TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) 
     IF TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) > 
      WS-MOST-USED-EXCUSE 
      MOVE TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) 
             TO WS-MOST-USED-EXCUSE 
     END-IF 
     ADD NUMBER-TIMES-USED TO WS-EXCUSE-TOTAL 
    ELSE 
     MOVE "Y" TO WS-INVALID-RECORD 
     MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
     MOVE INPUT-RECORD TO DLE-ERROR 
     MOVE ALL "*" TO DLE-EXCUSE 
    END-IF 
END-IF 

注意的TABLE-EXCUSES-COUNT的大小比WS-MOST-USED-EXCUSE规模更大。如果你这样保持,那么当你有超过99种相同类型的借口时,你会得到意想不到的行为。

您嵌套IF有点曲折,和你有一些重复。这里有一些简化:

IF (EXCUSE-NUMBER NUMERIC) 
    AND (VALID-EXCUSE) 
     PERFORM CHECK-NUMBER-TIMES-USED 
    ELSE 
     PERFORM SET-STANDARD-REJECTION 
     MOVE ALL "*" TO DLE-EXCUSE-NUMBER 
    END-IF 

... 

CHECK-NUMBER-TIMES-USED. 
    IF 88-level-first-byte-space 
     MOVE ZERO TO name-you've-given-the-first-byte 
    END-IF 
    IF 88-level-field-space 
     MOVE ZERO TO field 
    END-IF 
    IF NUMBER-TIMES-USED IS NUMERIC 
     ADD NUMBER-TIMES-USED TO TABLE-EXCUSES-COUNT (EXCUSE-NUMBER) 
           WS-EXCUSE-TOTAL 
     PERFORM CHECK-HIGHEST-EXCUSE-COUNT 
    ELSE 
     PERFORM SET-STANDARD-REJECTION 
     MOVE ALL "*" TO DLE-EXCUSE 
    END-IF 


SET-STANDARD-REJECTION. 
    MOVE INPUT-RECORD TO DLE-ERROR 
    MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
    MOVE "Y" TO WS-INVALID-RECORD 
    . 

CHECK-HIGHEST-EXCUSE-COUNT. 
    IF TABLE-EXCUSES-COUNT (EXCUSE-NUMBER) 
     GREATER THAN WS-COUNT-OF-MOST-USED 
     MOVE TABLE-EXCUSES-COUNT (EXCUSE-NUMBER) 
            TO WS-COUNT-OF-MOST-USED 
     MOVE EXCUSE-NUMBER  TO WS-EXCUSE 
    END-IF 
    . 

当你达到总数,但至少有一个简化,但看看如何。

+0

谢谢,我明白你的去向,我倾向于急于多想,而不仅仅是想... – 2015-02-09 13:31:40

1

VALID-借口可以很好地为

 EXCUSE-NUMBER >= '01' and EXCUSE-NUMBER < '12' 

所以在程序3000-工艺实现,我会尝试更换

IF NOT VALID-EXCUSE 
     MOVE INPUT-RECORD TO DLE-ERROR 
     MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
     MOVE "Y" TO WS-INVALID-RECORD 
     MOVE ALL "*" TO DLE-EXCUSE-NUMBER 
    END-IF. 

INSPECT EXCUSE-NUMBER REPLACING LEADING SPACES BY ZERO 
    IF EXCUSE-NUMBER is numeric 
    and VALID-EXCUSE 
     continue 
    else 
     MOVE INPUT-RECORD TO DLE-ERROR 
     MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
     MOVE "Y" TO WS-INVALID-RECORD 
     MOVE ALL "*" TO DLE-EXCUSE-NUMBER 
    END-IF 

    if not NUMBER-TIMES-USED is numeric 
     MOVE "Y" TO WS-INVALID-RECORD 
     MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
     MOVE INPUT-RECORD TO DLE-ERROR 
     MOVE ALL "*" TO DLE-EXCUSE 
    end-if 

也删除以下内容:

 ELSE 

      MOVE "Y" TO WS-INVALID-RECORD 
      MOVE WS-LINE-NUMBER TO DLE-LINE-NUMBER 
      MOVE INPUT-RECORD TO DLE-ERROR 
      MOVE ALL "*" TO DLE-EXCUSE 

此代码是完全错误的地方。

还有其他错误,例如

ADD EXCUSE-NUMBER TO TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) 

大概应该是

ADD 1    TO TABLE-EXCUSES-COUNT(EXCUSE-NUMBER) 
+0

我明白了你的观点,它确实有点意义,我认为我急于快速。 – 2015-02-09 13:21:33

+0

我非常感谢您的意见,现在正在计算出硬编码表以获得正确的计数,最常用的最高使用率是正确的,必须是另一个超过视线,再次感谢! – 2015-02-09 13:24:10