2015-09-30 20 views
1

我想我搞砸了,當我搞砸了它試圖找出它爲什麼它沒有工作。它只讀取我的數據的第一行,然後結束。 (它打印頭,數據的第一線,所有的都在300-過程的記錄計算,做最後的標題截至報告。與我的循環不好的語法,但沒有在COBOL中拋出錯誤

 FILE-CONTROL. 
     SELECT F01-INPUT-FILE ASSIGN TO 'I:\COBOL\EmployeePay.dat' 
           ORGANIZATION IS LINE SEQUENTIAL. 

     SELECT F02-PRINT-FILE ASSIGN TO 'I:\COBOL\EmployeePay.out' 
           ORGANIZATION IS LINE SEQUENTIAL. 

    DATA DIVISION. 
    FILE SECTION. 

    FD F01-INPUT-FILE 
     RECORD CONTAINS 30 CHARACTERS 
     DATA RECORD IS F01-INPUT-RECORD. 

    01 F01-INPUT-RECORD. 
     05 F01-EMPLOYEE-NAME  PIC X(18). 
     05 F01-EMPLOYEE-SSN   PIC 9(9). 
     05 F01-GROSS-PAY   PIC 9(3). 

    FD F02-PRINT-FILE 
     RECORD CONTAINS 86 CHARACTERS 
     DATA RECORD IS F02-PRINT-LINE-RECORD. 
    01 F02-PRINT-LINE-RECORD  PIC X(86). 

    WORKING-STORAGE SECTION. 

    01 W01-DATA-REMAINS-SWITCH  PIC X VALUE 'Y'. 

    01 W02-DETAIL-LINE. 
     05       PIC X(2) VALUE SPACES. 
     05 W02-EMPLOYEE-NAME  PIC X(18). 
     05       PIC X(2) VALUE SPACES. 
     05 W02-EMPLOYEE-SSN   PIC 9(9). 
     05       PIC X(7) VALUE SPACES. 
     05 W02-PAY-100S    PIC 9. 
     05       PIC X(5) VALUE SPACES. 
     05 W02-PAY-50S    PIC 9. 
     05       PIC X(4) VALUE SPACES. 
     05 W02-PAY-20S    PIC 9. 
     05       PIC X(4) VALUE SPACES. 
     05 W02-PAY-10S    PIC 9. 
     05       PIC X(4) VALUE SPACES. 
     05 W02-PAY-5S    PIC 9. 
     05       PIC X(4) VALUE SPACES. 
     05 W02-PAY-1S    PIC 9. 
     05       PIC X(3) VALUE SPACES. 
     05 W02-GROSS-PAY   PIC 9(3). 
     05       PIC X(15). 

    01 W02-HEADER-LINE1. 
     05       PIC X(22) VALUE SPACES. 
     05     PIC X(24) VALUE SPACES. 
     05       PIC X(40) VALUE SPACES. 

    01 W02-HEADER-LINE2. 
     05       PIC X(2) VALUE SPACES. 
     05       PIC X(13) VALUE 'EMPLOYEE NAME'. 
     05       PIC X(20) VALUE SPACES. 
     05       PIC X(4) VALUE '$100'. 
     05       PIC X(3) VALUE SPACES. 
     05       PIC X(3) VALUE '$50'. 
     05       PIC X(2) VALUE SPACES. 
     05       PIC X(3) VALUE '$20'. 
     05       PIC X(2) VALUE SPACES. 
     05       PIC X(3) VALUE '$10'. 
     05       PIC X(3) VALUE SPACES. 
     05       PIC X(2) VALUE '$5'. 
     05       PIC X(3) VALUE SPACES. 
     05       PIC X(2) VALUE '$1'. 
     05       PIC X(3) VALUE SPACES. 
     05       PIC X(3) VALUE 'PAY'. 
     05       PIC X(15) VALUE SPACES. 

    01 W02-CLOSING-LINE. 
     05       PIC X(13) VALUE 'End Of Report'. 
     05       PIC X(73) VALUE SPACES. 

    01 PAY       PIC 999V99. 

    PROCEDURE DIVISION. 

    PERFORM 100-OPEN-FILES. 
    PERFORM 200-WRITE-HEADING-LINES. 
    PERFORM 300-PROCESS-RECORDS 
     UNTIL W01-DATA-REMAINS-SWITCH = 'N'. 
    PERFORM 400-WRITE-FOOTER. 
    PERFORM 500-CLOSE-FILES. 

    100-OPEN-FILES. 
     OPEN INPUT F01-INPUT-FILE 
     OUTPUT F02-PRINT-FILE 
    READ F01-INPUT-FILE 
     AT END MOVE "N" TO W01-DATA-REMAINS-SWITCH 
     . 

    200-WRITE-HEADING-LINES. 
     MOVE W02-HEADER-LINE1 TO F02-PRINT-LINE-RECORD. 
     WRITE F02-PRINT-LINE-RECORD. 
     MOVE W02-HEADER-LINE2 TO F02-PRINT-LINE-RECORD. 
     WRITE F02-PRINT-LINE-RECORD. 


    300-PROCESS-RECORDS.   

     MOVE F01-EMPLOYEE-NAME TO W02-EMPLOYEE-NAME. 
     MOVE F01-EMPLOYEE-SSN TO W02-EMPLOYEE-SSN. 
     MOVE F01-GROSS-PAY TO W02-GROSS-PAY. 

     PERFORM 310-DO-CALCULATIONS. 

     MOVE W02-DETAIL-LINE TO F02-PRINT-LINE-RECORD. 
     WRITE F02-PRINT-LINE-RECORD. 
    READ F01-INPUT-FILE 
     AT END MOVE 'N' TO W01-DATA-REMAINS-SWITCH 
     END-READ. 

    310-DO-CALCULATIONS. 
     COMPUTE W02-PAY-100S = W02-GROSS-PAY/100 
     COMPUTE PAY = W02-GROSS-PAY - (W02-PAY-100S * 100)               
     COMPUTE W02-PAY-50S = PAY/50 
     COMPUTE PAY = PAY - (W02-PAY-50S * 50) 
     COMPUTE W02-PAY-20S = PAY/20 
     COMPUTE PAY = PAY - (W02-PAY-20S * 20) 
     COMPUTE W02-PAY-10S = PAY/10 
     COMPUTE PAY = PAY - (W02-PAY-50S * 10) 
     COMPUTE W02-PAY-5S = PAY/5 
     COMPUTE PAY = PAY - (W02-PAY-5S * 5) 
     COMPUTE W02-PAY-1S = PAY/1 
     . 

    400-WRITE-FOOTER. 

     MOVE W02-CLOSING-LINE TO F02-PRINT-LINE-RECORD. 
     WRITE F02-PRINT-LINE-RECORD. 


    500-CLOSE-FILES. 
     CLOSE F01-INPUT-FILE 
      F02-PRINT-FILE. 

的單位計算不得不在那裏,我明白了使用它只是一個數學的東西,我被卡住了,他們現在工作=)

所以,也許我誤解了你的答案,但修復它並沒有改變任何東西。它仍然只返回文件中的一行數據並結束。

+0

什麼語法不好?注意它應該是'直到W01-DATA-REMAINS-SWITCH =「N」'。 – EJP

+0

對你的其他問題的任何反饋?我看到你已經保存了大量的'計算',包括除以1。只對傳球感興趣?標題是什麼?你在文字上犯了一個錯字。你如何期望編譯器,任何編譯器或解釋器或其他東西以某種方式將其視爲「語法」問題?建議您更改@EJP,並將其傳入。 –

回答

0

兩個顯而易見的問題:

  1. 讀statements2。看起來是在錯誤的列
  2. 的無循環語句
  3. 您需要設置W01-DATA-仍然-SWITCH爲Y,然後再開始

嘗試

100-OPEN-FILES. 
    OPEN INPUT F01-INPUT-FILE 
    OUTPUT F02-PRINT-FILE 
    READ F01-INPUT-FILE 
     AT END MOVE "N" TO W01-DATA-REMAINS-SWITCH 
    end-Read 

    PERFORM UNTIL W01-DATA-REMAINS-SWITCH = "N" 

     .... 

     READ F01-INPUT-FILE 
      AT END MOVE "N" TO W01-DATA-REMAINS-SWITCH 
     end-read 
    end-perform 

  1. 查找 levels and the set verb eg

    SET EOF   to true 
    
  2. 發現多出了COBOL應該如何格式化

+0

謝謝@BillWoodger,這是一個糟糕的錯失;更新回答 –

+0

爲什麼不嘗試將W01-DATA-REMAINS-SWITCH初始化爲Y? –

+0

@ user3556888布魯斯發現了最新的錯誤。您切換需要非N值,然後設置爲N'AT END'。如果PERFORM的條件最初是真實的,那麼PERFORM從未被輸入。您不需要更改初始值。 –

3

你患有「下穿」或「落空」。

我會很快進入,但首先還有其他一些事情。

您的標題:Bad syntax with my loop, but not throwing an error in COBOL。我對問題的建議是兩個最後寫的標題,那麼你更有可能避免這個問題。沒有「語法」問題,編譯器無法爲您提供幫助。

其次,你的問題描述:「我的閱讀循環有一些麻煩,它不會繼續通過循環。」

該含義尚不清楚。我們讀入一個含義(循環根本沒有輸入),而你的意思是另一個(只有一個記錄,文件中的第一個記錄出現在輸出中)。

這個問題的重要性如下:如果現有代碼的解釋沒有準確地獲得所獲得的輸出,那麼這當然不是對問題的完整解釋:直到您知道爲止,才更改一行代碼充分的解釋。

好吧,好的,但是你經常想做一些改變來幫助確定問題,或者只是爲了希望能夠發生一些魔法並且解決問題。那麼,不要去原來的程序。複製程序。如果你想這樣做,我們不想指出你嘗試過的兜風和黑客的副作用。

在我們的閱讀,在Y/Y和N/N問題解釋什麼(我們認爲),你都拿到。但是,它並沒有解釋實際產出。我們怎麼知道?你沒有包含任何輸出。

有時候問題是一個「空」的文件,或者只有一個記錄,或者確實是一個「腐敗」文件的文件(TIP它5英鎊,它會採取第三潛水)。除了不太可能的情況外,如果不包含樣本數據,我們是否會排除這些數據?

然後,我們需要看到不工作的代碼。但是,如果你知道那是什麼不起作用,很可能你會得到答案。所以,你必須盡最大努力將代碼減少到最小的數量,但仍然存在問題。

因此,一個好的標題,一旦問題完成就定案;準確的問題陳述;樣本輸入數據,實際產出,預期產出;錯誤消息(完整,錯誤代碼)(如果有的話);產生問題的最小示例代碼。

通常情況下,在準備好一個很好的問題,你會得到答案自己反正之前,你甚至需要問。

一個好方法就是向別人解釋你的問題。閱讀和說話你會閱讀的不僅僅是閱讀(對你自己)和假設。即使你沒有同事/朋友,只要假裝你有一個Cardboad-Cutout程序員(可以是充氣的,就像自動駕駛儀總是在喜劇電影中一樣),或者一個蛋杯或者橡皮鴨(顯然這是一個也適用)。

哦,我會在你的其他問題上更新我的答案。

因此,「跨越」或「下穿」。

MOVE X      TO Y 
    . 
some-paragraph-name. 
    MOVE A      TO B 
    ... 

在那裏您會看到一個段落名稱。段落名稱後控件如何直接傳遞到行?普通代碼有三種有效的,合法的和可用的方式(非聲明,非SORT過程):在執行MOVE X之後,如果代碼不在範圍以「some-paragraph-name」結束的PERFORM中,則MOVE A將是下一個;去一些段落名稱;部分段落名稱的PERFORM(在某些變體中)。

(注意,有什麼適用於上文第同樣適用於部分中的過程DIVISION)。

這與許多其他語言不同,其中「函數」或「子例程」將受到代碼主流程的「保護」,它們不能「落入」或轉到。

在COBOL,越來越有完全有效的,甚至在同一個程序的同款名完全有效(有效期不,當然,意味着好的做法的三種方法:好的做法將妨礙這種使用)。

由於所有的方法都是完全合法,編譯器也沒什麼好說的,當你使用的方法之一,即使它的使用是意外(如何將編譯器知道嗎?)。

這是你的問題:

PERFORM 500-CLOSE-FILES. 

100-OPEN-FILES. 

我突出的線,可惜的是,因爲沒有什麼它不會顯示出來就行了。

PERFORM 500-CLOSE-FILES 
    GOBACK (or STOP RUN, or EXIT PROGRAM, but GOBACK is better) 
    . 
100-OPEN-FILES. 

所以,你的程序運行,處理整個輸入一次文件中的記錄,同時將數據寫入到輸出文件,創歷史新高。一切接近確定。

然後你關閉了文件。

然後你掉到了100-OPEN-FILES和BANG!你的輸出被擦除。然後它進行第一次閱讀。然後是300-,只是一次,所以在讀取下一個記錄之前先處理一條記錄,然後下降到310-,然後是400-,然後是500-,這會關閉文件並從程序結束時落下,導致執行停止。

實際上,根據編譯器的不同,程序中至少應該有一個終止語句,並且程序中有一個失敗。但是,您正在使用的編譯器不會這樣做(或者您已經告訴它不要使用選項/開關來執行此操作)。

添加GOBACK /停止運行/退出程序和您的程序將工作。通常。

你怎麼能自己發現這一點?計數輸入和輸出記錄並在程序結束時顯示總計通常是有幫助的。如果你使用FILE STATUS,你不會懷疑它是一個狡猾的文件。正如布魯斯已經建議的那樣,格式良好,使用88。