【问题标题】:COBOL adding an arrayCOBOL 添加数组
【发布时间】:2015-10-07 12:57:54
【问题描述】:

我希望我的程序输出输入的数组,然后显示我输入的总量。总值是错误的,我的程序中的数组中的值发生了变化。我认为我的问题是添加部分。我应该如何解决它?

 IDENTIFICATION DIVISION.
 PROGRAM-ID. FOREXCHANGE.
 DATA DIVISION.
 WORKING-STORAGE SECTION.
   01 CURR-VAL.
      02 USD  PIC 999V99 VALUE 46.59.
      02 AUS  PIC 999V99 VALUE 32.87.
      02 CND  PIC 999V99 VALUE 36.37.
      02 EUR  PIC 999V99 VALUE 52.32.
      02 YEN  PIC 999V99 VALUE 0.40.
      02 NZD  PIC 999V99 VALUE 30.04.
      02 OMN  PIC 999V99 VALUE 120.99.
      02 SGD  PIC 999V99 VALUE 32.52.
   77 AMOUNT      PIC 9(6)V99.
   77 NEWVAL      PIC 9(4)V99.
   77 ROUNDOFF    PIC ZZZ,ZZ9.99.
   77 VALCUR      PIC 9(6)V99.
   77 FORCUR      PIC X(3).
   77 TRANSAC     PIC 9(4) OCCURS 9999 TIMES.
   77 CURRENCIES  PIC X(3) OCCURS 9999 TIMES.
   77 AMOUNTARR   PIC 9(6)V99 OCCURS 9999 TIMES.
   77 AMOUNTTOT   PIC 9(6)V99 OCCURS 9999 TIMES.
   77 TRANSACNUM  PIC 9(4) VALUE 0001.
   77 CTR         PIC 9(4) VALUE ZERO.
   77 CTR1        PIC 9(4) VALUE ZERO.
   77 CURINDEX    PIC 9 VALUE 0.
   77 CHOICE      PIC X. 
 PROCEDURE DIVISION.
  MAIN-MENU.
     DISPLAY ERASE.
     DISPLAY "MAIN MENU".
     DISPLAY "1. TRANSACTION".
     DISPLAY "2. UPDATE".
     DISPLAY "3. SUMMARY".
     DISPLAY "4. EXIT".
     DISPLAY "ENTER CHOICE: " WITH NO ADVANCING.
     ACCEPT CHOICE.
     IF CHOICE = "1"
        PERFORM ADDTRANS
     ELSE IF CHOICE = "2"
        PERFORM UPDATES
     ELSE IF CHOICE = "3"
        PERFORM SUMMARIES 
     ELSE IF CHOICE = "4"
        STOP RUN
     ELSE 
        DISPLAY "INVALID CHOICE! PLEASE TRY AGAIN!"
        PERFORM MAIN-MENU.

  SUMMARIES.
     DISPLAY ERASE.
     DISPLAY "SUMMARY".
     DISPLAY "TRANSACTION NUMBER   CURRENCY   AMOUNT".
     PERFORM WITH TEST AFTER VARYING CTR FROM 1 BY 1 
           UNTIL CTR = CURINDEX

             DISPLAY "          " TRANSAC(CTR) WITH NO ADVANCING
             DISPLAY "         " WITH NO ADVANCING
             DISPLAY CURRENCIES(CTR)WITH NO ADVANCING
             MOVE AMOUNTARR(CTR) TO ROUNDOFF
             DISPLAY "      " ROUNDOFF
     END-PERFORM.
     PERFORM WITH TEST AFTER VARYING CTR FROM 1 BY 1 
           UNTIL CTR = CURINDEX
                 ADD AMOUNTARR(CTR) TO AMOUNTARR(CTR)
     END-PERFORM.

     MOVE AMOUNTARR(CURINDEX) TO ROUNDOFF.
     DISPLAY "TOTAL PHP" ROUNDOFF.
     DISPLAY "GO BACK TO MAIN MENU?:[Y/N] " 
             WITH NO ADVANCING.
     ACCEPT CHOICE.
     IF CHOICE = "Y"
         PERFORM MAIN-MENU
     ELSE IF CHOICE = "N"
         PERFORM SUMMARIES
     ELSE
         DISPLAY "INVALID CHOICE! GOING BACK TO MAIN MENU"
         PERFORM MAIN-MENU. 

  ADDTRANS. 
     DISPLAY ERASE.
     ADD 1 TO CURINDEX.
     DISPLAY "TRANSACTION NUMBER: " TRANSACNUM.
     MOVE TRANSACNUM TO TRANSAC(CURINDEX).
     ADD 1 TO TRANSACNUM. 
     DISPLAY "ENTER FOREIGN CURRENCY: " WITH NO ADVANCING.
     ACCEPT FORCUR.
     IF FORCUR = "USD"
        MOVE USD TO VALCUR
        DISPLAY "ENTER AMOUNT: $" WITH NO ADVANCING
        ACCEPT AMOUNT
     ELSE IF FORCUR = "AUS"
        MOVE AUS TO VALCUR
        DISPLAY "ENTER AMOUNT: $" WITH NO ADVANCING
        ACCEPT AMOUNT
     ELSE IF FORCUR = "CND"
        MOVE CND TO VALCUR
        DISPLAY "ENTER AMOUNT: $" WITH NO ADVANCING
        ACCEPT AMOUNT
     ELSE IF FORCUR = "EUR"
        MOVE EUR TO VALCUR
        DISPLAY "ENTER AMOUNT: E" WITH NO ADVANCING
        ACCEPT AMOUNT
     ELSE IF FORCUR = "YEN"
        MOVE YEN TO VALCUR
        DISPLAY "ENTER AMOUNT: Y" WITH NO ADVANCING
        ACCEPT AMOUNT
     ELSE IF FORCUR = "NZD"
        MOVE NZD TO VALCUR
        DISPLAY "ENTER AMOUNT: $" WITH NO ADVANCING
        ACCEPT AMOUNT
     ELSE IF FORCUR = "OMN"
        MOVE OMN TO VALCUR
        DISPLAY "ENTER AMOUNT: R" WITH NO ADVANCING
        ACCEPT AMOUNT
     ELSE IF FORCUR = "SGD"
        MOVE SGD TO VALCUR
        DISPLAY "ENTER AMOUNT: $" WITH NO ADVANCING
        ACCEPT AMOUNT
     ELSE
        DISPLAY "INVALID FOREIGN CURRENCY! PLEASE TRY AGAIN!" 
        SUBTRACT 1 FROM CURINDEX
        SUBTRACT 1 FROM TRANSACNUM
        PERFORM MAIN-MENU.
     MOVE FORCUR TO CURRENCIES(CURINDEX).
     MULTIPLY AMOUNT BY VALCUR GIVING AMOUNTARR(CURINDEX).
     MOVE AMOUNTARR(CURINDEX) TO ROUNDOFF.
     DISPLAY "PHP " ROUNDOFF.
     DISPLAY "ENTER ANOTHER TRANSACTION?:[Y/N] " 
             WITH NO ADVANCING.
     ACCEPT CHOICE.
     IF CHOICE = "Y"
         PERFORM ADDTRANS
     ELSE IF CHOICE = "N"
         PERFORM MAIN-MENU
     ELSE
         DISPLAY "INVALID CHOICE! GOING BACK TO MAIN MENU"
         PERFORM MAIN-MENU.

  UPDATES.
     DISPLAY ERASE.
     DISPLAY "ENTER FOREIGN CURRENCY: " WITH NO ADVANCING.
     ACCEPT FORCUR.
     IF FORCUR = "USD"
        MOVE USD TO ROUNDOFF
        DISPLAY "RECENT VALUE: " ROUNDOFF
        DISPLAY "RATE: $" WITH NO ADVANCING
        ACCEPT NEWVAL
        MOVE NEWVAL TO USD
     ELSE IF FORCUR = "AUS"
        MOVE AUS TO ROUNDOFF
        DISPLAY "RECENT VALUE: " ROUNDOFF
        DISPLAY "RATE: $" WITH NO ADVANCING
        ACCEPT NEWVAL
        MOVE NEWVAL TO AUS
     ELSE IF FORCUR = "CND"
        MOVE CND TO ROUNDOFF
        DISPLAY "RECENT VALUE: " ROUNDOFF
        DISPLAY "RATE: $" WITH NO ADVANCING
        ACCEPT NEWVAL
        MOVE NEWVAL TO CND
     ELSE IF FORCUR = "EUR"
        MOVE EUR TO ROUNDOFF
        DISPLAY "RECENT VALUE: " ROUNDOFF
        DISPLAY "RATE: E" WITH NO ADVANCING
        ACCEPT NEWVAL
        MOVE NEWVAL TO EUR
     ELSE IF FORCUR = "YEN"
        MOVE YEN TO ROUNDOFF
        DISPLAY "RECENT VALUE: " ROUNDOFF
        DISPLAY "RATE: Y" WITH NO ADVANCING
        ACCEPT NEWVAL
        MOVE NEWVAL TO YEN
     ELSE IF FORCUR = "NZD"
        MOVE NZD TO ROUNDOFF
        DISPLAY "RECENT VALUE: " ROUNDOFF
        DISPLAY "RATE: $" WITH NO ADVANCING
        ACCEPT NEWVAL
        MOVE NEWVAL TO NZD
     ELSE IF FORCUR = "OMN"
        MOVE OMN TO ROUNDOFF
        DISPLAY "RECENT VALUE: " ROUNDOFF
        DISPLAY "RATE: R" WITH NO ADVANCING
        ACCEPT NEWVAL
        MOVE NEWVAL TO OMN
     ELSE IF FORCUR = "SGD"
        MOVE SGD TO ROUNDOFF
        DISPLAY "RECENT VALUE: " ROUNDOFF
        DISPLAY "RATE: $" WITH NO ADVANCING
        ACCEPT NEWVAL
        MOVE NEWVAL TO SGD
     ELSE
        DISPLAY "INVALID FOREIGN CURRENCY! PLEASE TRY AGAIN!" 
        PERFORM MAIN-MENU.
     DISPLAY "--GO BACK TO MAIN MENU".
     PERFORM MAIN-MENU.

更新: 我设法修复了数组中值的变化,但添加仍然是错误的。我发现了问题。数组中的最后一个值添加到自身。

SUMMARIES.
 DISPLAY ERASE.
 DISPLAY "SUMMARY".
 DISPLAY "TRANSACTION NUMBER   CURRENCY   AMOUNT".
 PERFORM WITH TEST AFTER VARYING CTR FROM 1 BY 1 
       UNTIL CTR = CURINDEX

         DISPLAY "          " TRANSAC(CTR) WITH NO ADVANCING
         DISPLAY "         " WITH NO ADVANCING
         DISPLAY CURRENCIES(CTR)WITH NO ADVANCING
         MOVE AMOUNTARR(CTR) TO ROUNDOFF
         DISPLAY "      " ROUNDOFF
 END-PERFORM.

 PERFORM WITH TEST AFTER VARYING CTR1 FROM 1 BY 1 
       UNTIL CTR1 = CURINDEX
             MOVE AMOUNTARR(CTR1) TO AMOUNTTOT(CTR1)
             ADD AMOUNTTOT(CTR1) TO AMOUNTTOT(CTR1)
 END-PERFORM.

【问题讨论】:

  • 您使用的是什么 COBOL 编译器?具有 OCCURS 的 77 级是非标准的。 77级已经不需要了,最好都是01级。

标签: arrays cobol


【解决方案1】:

您不能使用 PERFORM 如何使用它。 PERFORM 不能以任何方式递归。

即使可以,这也将是“意大利面条”代码:您无法确定自己在程序中的哪个位置,除非您知道当时自己来自哪里。你从一条蜿蜒曲折的路线走到另一条。

另一个问题是你到处“跌倒”。如果您从紧接其前一行到达一个段落,则该段落将执行。这解释了您显然是随机添加的。

您的程序中的代码可能就在那里,但您需要对其进行完全重组。如果您在此处查看一些 COBOL 问题的答案,您会看到一些示例代码给您大致的想法。

这应该类似于您的控制结构:

 ACCEPT CHOICE
 PERFORM UNTIL CHOICE EQUAL TO "4"
     IF CHOICE = "1"
        PERFORM ADDTRANS
     ELSE IF CHOICE = "2"
        PERFORM UPDATES
     ELSE IF CHOICE = "3"
        PERFORM SUMMARIES 
     ELSE 
        DISPLAY "INVALID CHOICE! PLEASE TRY AGAIN!"
     END-IF
     END-IF
     END-IF
     ACCEPT CHOICE
 END-PERFORM

您应该将nested-IFs 更改为EVALUATE,并且应该将字段上的文字值测试更改为88s,COBOL 的condition-names

必须重组您的程序。目前,它是行不通的,不可靠的,不可移植的,没有任何用处。但是,只有结构(可能)是错误的。如果您掌握了如何构建程序,以及如何通过/转到段落(除非您看不到不这样做的方法,否则不要这样做,有经验总有方法不这样做) to)/PERFORMed。

最近有一个问题的答案是“失败”。阅读:https://stackoverflow.com/a/32885852/1927206

请记住,虽然结构错误,但代码是可以挽救的。这是 COBOL 初学者常犯的错误,所以问题不大。很适合学习。试试看这里的例子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    相关资源
    最近更新 更多