使用GO-TO语句时遇到问题。这应该运行直到用户键入' END'。如果我输入' END'当我第一次打开程序时,它会关闭,但是如果我在输入第一次通过的有效数据后输入它,它就会继续返回用户输入数据屏幕。
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT USED-CAR-FILE-OUT
ASSIGN TO 'USED-CAR.RPT'
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD USED-CAR-FILE-OUT.
01 USED-CAR-RECORD-OUT PIC X(80).
WORKING-STORAGE SECTION.
01 FIRST-RECORD PIC X(3) VALUE 'YES'.
01 ID-CODE PIC X(3).
01 TOTAL-CASH-PAYMENT PIC 9(5).
01 MONTHLY-PAYMENT PIC 9(4).
01 NUMBER-OF-MONTHS PIC 9(3).
01 TOTAL-BALANCE PIC S9(6)V99 VALUE ZEROS.
01 INTEREST-COLLECTED PIC 99V99 VALUE ZEROS.
01 MONTH-DIFF PIC 99 VALUE ZEROS.
01 MONTH-NUM PIC 99 VALUE ZEROS.
01 YEAR-NUM PIC 99 VALUE ZEROS.
01 ID-HOLD PIC X(3) VALUE SPACES.
01 PAYMENT-HOLD PIC X(3) VALUE SPACES.
01 DETAIL-LINE.
05 ID-CODE-DL PIC X(3).
05 PIC X(3) VALUE SPACES.
05 PIC X(4) VALUE 'Yr='.
05 YEAR-NUMBER-DL PIC Z9.
05 PIC X(4) VALUE SPACES.
05 PIC X(4) VALUE 'MO='.
05 MONTH-NUMBER-DL PIC Z9.
05 PIC X(4) VALUE SPACES.
05 PIC X(5) VALUE 'Pmt='.
05 PAYMENT-DL PIC $$$,$$$.
05 PIC X(4) VALUE SPACES.
05 PIC X(5) VALUE 'Int='.
05 INTEREST-EARNED-DL PIC $$$$.99.
05 PIC X(3) VALUE SPACES.
05 PIC X(5) VALUE 'Bal='.
05 BALANCE-DL PIC $$$,$$$.99.
PROCEDURE DIVISION.
100-MAIN.
OPEN OUTPUT USED-CAR-FILE-OUT
PERFORM 200-USER-INPUT THRU 299-EXIT
CLOSE USED-CAR-FILE-OUT
STOP RUN.
200-USER-INPUT.
DISPLAY 'Used Car Sales Report'
DISPLAY 'Enter the ID code (or END) - maxium three char.'
ACCEPT ID-CODE
IF ID-CODE = 'END'
GO TO 299-EXIT
END-IF
DISPLAY 'Enter the Total Cash Payment - maximum five digits'
ACCEPT TOTAL-CASH-PAYMENT
DISPLAY 'Enter the Monthly Payment - maximum four digits'
ACCEPT MONTHLY-PAYMENT
DISPLAY 'Enter the Number of Months - maximum three digits'
ACCEPT NUMBER-OF-MONTHS
PERFORM 300-RECORD-PROCESS.
299-EXIT.
EXIT.
300-RECORD-PROCESS.
IF TOTAL-CASH-PAYMENT > 0
IF FIRST-RECORD = 'YES'
MOVE ID-CODE TO ID-CODE-DL
MOVE 1 TO YEAR-NUMBER-DL
MOVE 1 TO YEAR-NUM
move 1 to MONTH-NUMBER-DL
MOVE TOTAL-CASH-PAYMENT TO PAYMENT-DL
MOVE PAYMENT-DL TO MONTHLY-PAYMENT
ADD MONTHLY-PAYMENT TO TOTAL-BALANCE
MOVE 'NO' TO FIRST-RECORD
END-IF
COMPUTE INTEREST-COLLECTED ROUNDED = TOTAL-BALANCE
* .0175 / 12
MOVE INTEREST-COLLECTED TO INTEREST-EARNED-DL
ADD INTEREST-COLLECTED TO TOTAL-BALANCE
MOVE TOTAL-BALANCE TO BALANCE-DL
ADD 1 TO MONTH-DIFF
MOVE MONTH-DIFF TO MONTH-NUMBER-DL
IF MONTH-NUMBER-DL > 13
ADD 1 TO MONTH-NUM
MOVE MONTH-NUM TO MONTH-NUMBER-DL
END-IF
IF MONTH-NUMBER-DL = 13
MOVE 1 TO MONTH-NUM
MOVE MONTH-NUM TO MONTH-NUMBER-DL
END-IF
IF MONTH-NUM = 1
ADD 1 TO YEAR-NUM
MOVE YEAR-NUM TO YEAR-NUMBER-DL
END-IF
MOVE DETAIL-LINE TO USED-CAR-RECORD-OUT
WRITE USED-CAR-RECORD-OUT
AFTER ADVANCING 1 LINE
MOVE ID-HOLD TO ID-CODE-DL
IF MONTH-DIFF < NUMBER-OF-MONTHS
PERFORM 300-RECORD-PROCESS
END-IF
PERORM 200-USER-INPUT
END-IF
IF MONTHLY-PAYMENT > 0
IF FIRST-RECORD = 'YES'
MOVE ID-CODE TO ID-CODE-DL
MOVE 1 TO YEAR-NUMBER-DL
MOVE 1 TO YEAR-NUM
move 1 to MONTH-NUMBER-DL
MOVE 'NO' TO FIRST-RECORD
END-IF
MOVE MONTHLY-PAYMENT TO PAYMENT-DL
MOVE PAYMENT-DL TO MONTHLY-PAYMENT
ADD MONTHLY-PAYMENT TO TOTAL-BALANCE
COMPUTE INTEREST-COLLECTED ROUNDED = TOTAL-BALANCE
* .0175 / 12
MOVE INTEREST-COLLECTED TO INTEREST-EARNED-DL
ADD INTEREST-COLLECTED TO TOTAL-BALANCE
MOVE TOTAL-BALANCE TO BALANCE-DL
ADD 1 TO MONTH-DIFF
MOVE MONTH-DIFF TO MONTH-NUMBER-DL
IF MONTH-NUMBER-DL > 13
ADD 1 TO MONTH-NUM
MOVE MONTH-NUM TO MONTH-NUMBER-DL
END-IF
IF MONTH-NUMBER-DL = 13
MOVE 1 TO MONTH-NUM
MOVE MONTH-NUM TO MONTH-NUMBER-DL
END-IF
IF MONTH-NUM = 1
ADD 1 TO YEAR-NUM
MOVE YEAR-NUM TO YEAR-NUMBER-DL
END-IF
MOVE DETAIL-LINE TO USED-CAR-RECORD-OUT
WRITE USED-CAR-RECORD-OUT
AFTER ADVANCING 1 LINE
MOVE ID-HOLD TO ID-CODE-DL
IF TOTAL-CASH-PAYMENT > 0
MOVE 0 TO TOTAL-CASH-PaYMENT
MOVE 0 TO PAYMENT-DL
END-IF
IF MONTH-DIFF < NUMBER-OF-MONTHS
PERFORM 300-RECORD-PROCESS
END-IF
PERFORM 200-USER-INPUT
END-IF.
EDIT解决了以下问题 如果几个月,我也会遇到问题。 24.我逐步完成程序,它显示我的最后一个细节线作为正确的结果,但我的输出在24个月停止。提前致谢。
答案 0 :(得分:4)
AAAAAAAk!
执行严重殴打 - 通过提示 - 通过执行
使用重型物体
直到承诺 - 从未提取过 - 再次 - 请
执行即 EVIL 。它会导致与布局相关的代码。
在顶级控制级别,使用
PERFORM 200-USER-INPUT
UNTIL ID-CODE = 'END'.
(或者可能在ID-CODE上使用88 USER-INPUT-ENDED - 样式问题)
如何确定是否继续输入200 -...是您的选择,
IF NOT USER-INPUT-ENDED
DISPLAY 'Enter the Total Cash Payment - maximum five digits'
ACCEPT TOTAL-CASH-PAYMENT
...
ACCEPT NUMBER-OF-MONTHS
PERFORM 300-RECORD-PROCESS.
OR
IF NOT USER-INPUT-ENDED
PERFORM 210-ACCEPT-DETAILS.
210-ACCEPT-DETAILS.
DISPLAY 'Enter the Total Cash Payment - maximum five digits'.
ACCEPT TOTAL-CASH-PAYMENT.
...
ACCEPT NUMBER-OF-MONTHS.
PERFORM 300-RECORD-PROCESS.
因为你PERFORMED 200 -...然后只会执行200 -... 210 -...是一个新段落,只能从200 -... IF END
进入。
下一步是稍微修改300 -...
在200 -...中的PERFORM 300 -...之前移动初始化(FIRST-RECORD ='YES'代码),然后将PERFORM 300-RECORD-PROCESS.
修改为
PERFORM 300-RECORD-PROCESS
UNTIL TOTAL-BALANCE = 0.
(我在这里假设这是报告终止条件;如果不是,则替换报告终止条件)
您现在可以重组300 -...来计算应付利息,修改年份和月份数字并显示结果。 所有在300 -...中的PERFORM
将消失。
所以,实质上你有
MAIN:perform user-input until end-detected.
user-input: get user data; perform calculations until balance is zero.
calculations: one month's calculations at a time.
这也有一个好处,如果你选择,你可以插入
IF MONTHLY-PAYMENT IS LESS THAN INTEREST-COLLECTED
MOVE 'ERR' TO ID-CODE.
在ID-CODE中使用'ERR'在300 -...而不是渐进式报告行AND中产生适当的错误消息,同时将0
分配给TOTAL-BALANCE,终止{ {1}}。
答案 1 :(得分:1)
你的问题是你为自己创造了一个无限循环。你200段执行300段,你的300段执行你的200段。
您需要重新构建您的计划。
一个名为200-USER-INPUT的段落应该关注它。
repeat until end of input
get some input
if there is input to process
process the input
Yoiks!我刚刚注意到你在300以内的PERFORM 300 - !
答案 2 :(得分:1)
使用GO TO和PERFORM THROUGH段落范围已经破坏了COBOL的过程返回机制 用于维护适当的程序控制流程。实质上,你有一个无效的程序 - 它可能会编译 没有错误但根据COBOL的规则仍然是无效的程序。
以下是从控制流的角度来看程序正在做什么的概述。该 主线计划基本上是:
100-MAIN.
PERFORM 200-USER-INPUT THRU 299-EXIT
这要求COBOL执行从头开始找到的所有代码 200-USER-INPUT直到299-EXIT结束。这些大纲 程序是:
200-USER-INPUT.
IF some condition GO TO 299-EXIT
...
PERFORM 300-RECORD-PROCESS
.
299-EXIT.
请注意,如果some condition
为真,则程序流将跳过结束
200-USER-INPUT并跳转到299-EXIT。 299-EXIT什么都不做
非常有趣,它只是一个空段落作为一个结束
执行段落范围。
在段落300-RECORD-PROCESS中,您有相当多的代码。有趣的 位是:
300-RECORD-PROCESS.
...
PERFORM 200-USER-INPUT
请注意,PERFORM 200-USER-INPUT
这不是PERFORM THRU,因为您已在100-MAIN中编码。
问题是,当你回到200-USER-INPUT并且some codition
变成时
true(当你输入'EXIT'时),控制流程
跳到段落结尾的299-EXIT
你现在正在表演。从这一点来说
转发COBOL使用的控制机制流程来管理来自PERFORM动词的返回
已经腐败了。不再有正常的控制机制流程返回到200-USER-INPUT的位置
是在300-RECORD-PROCESS中进行的。
接下来发生的事情并不是大多数程序员所期望的。大多数程序员似乎都在期待 当达到299-EXIT结束时,程序流程应该返回到最后一个PERFORM的位置 已经完成。在这种情况下,就在PERFORM 200-USER-INPUT之后。不,COBOL不会那样工作,控制流程 将继续299-EXIT之后的下一个可执行语句。这会让你 回到300-RECORD-PROCESS中的第一个可执行语句!这就是你的原因 没有得到这个计划的预期行为。
COBOL程序中的逻辑流程必须确保执行过程的结束 总是以与它们相反的顺序到达。这对应于呼叫/返回 堆栈语义 大多数程序员都熟悉。
我的建议是避免使用PERFORM THRU
和GO TO
。这是两个最大的
今天用COBOL编程语言留下的邪恶。这些结构是一个悬念
过去的编程时代,今天没有建设性的好处。