2015-02-09 125 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