如何修复 COBOL 程序中打印二维 table 代码中的错误?

How to fix bug in code for printing two-dimensional table in COBOL program?

我正在创建一个在 unix 上使用 COBOL 处理房地产数据的程序。该程序同时打印一维 table 和二维 table(二维 table 的行代表卧室的数量,列代表浴室的数量)。我想知道为什么我不能更改这行代码:

 01 Accum-table2.
      02 Bed-Accum2 occurs 6 pic 9(9)v99 value zero.
         02 Bath-Accum2 occurs 3 
           pic 9(9)v99 value zero.

到这行代码:

       01 Accum-table2.
         02 Bed-Accum2 occurs 6 pic 9(9)v99 value zero.
              03 Bath-Accum2 occurs 3 
                  pic 9(9)v99 value zero.

^^这会导致层次结构错误,尽管我认为这是我的二维 table 打印错误的来源。

期望的输出:

                                   Baths  
                 1          2          3          4          5

     Bedrms
            1

            2

            3

                    ..etc..  

现在查看完整代码:

   IDENTIFICATION DIVISION.
    PROGRAM-ID. prog5.
    Author. Raoul Duke.      


    ENVIRONMENT DIVISION.
    Input-output Section.
    File-Control.
            select input-file assign to 
              "/home1/c/a/acsi203/realestate.dat".
            select input-file2 assign to
              "/home1/c/a/acsi203/city.dat".
            select output-file assign to "prog5out.dat"
               organization is line sequential. 
            select error-file assign to "error5out.dat"
               organization is line sequential.        

    DATA    DIVISION.
    File    Section.
    FD      Input-File.
    01      INPUT-REC.
            02 PropertyAddress  pic x(27).
            02 City             pic a(15).
            02 Zip              pic 9(5).
            02 State            pic a(2).
              88 Valid-State    value "CA".
            02 Bedrooms         pic 9.
            02 Bathrooms        pic 9.
            02 SqFt             pic 9(4).
            02 PropertyType     pic x(8).
              88 Valid-Prop     value "Resident"
                  "Condo" "Multi-Fa".
            02 SaleDayofWeek    pic a(3).
            02 Filler           pic x(1).
            02 SaleMonth        pic a(3).
            02 Filler           pic x(1).
            02 SaleDay          pic 9(2).
            02 Filler           pic x(1).
            02 SaleHour         pic 9(2).
            02 Filler           pic x(1).
            02 SaleMinute       pic 9(2).
            02 Filler           pic x(1).
            02 SaleSecond       pic 9(2).
            02 Filler           pic x(1).
            02 TimeZone         pic a(3).
            02 Filler           pic x(1).
            02 SaleYear         pic 9(4).
            02 SalePrice        pic 9(6).
            02 PropertyLatitude pic 99v999999.
            02 PropertyLongitude pic 99v9(7).
            02 filler pic x. 
    FD      Input-File2.
    01      INPUT-REC2.
            02 City2            pic a(15).
            02 Tax-Rate1        pic V999.
            02 Filler           pic x.

    FD  OUTPUT-FILE
        linage is 58 lines
        with footing at 55
        lines at top 5
        lines at bottom 5.
    01  OUTPUT-REC              pic x(132).

    FD  ERROR-FILE.
    01  Error-rec               pic x(132).

    WORKING-STORAGE SECTION.
    01 REPORT-HEADER.

            02 Filler           pic x(49) value spaces.
            02 Filler           pic x(70) value 
              "Sacramento Area Real Estate Transactions".
            02 Filler           pic x(61) value spaces.
    01 CURRENT-DATE.
            02 CurrentYear-out      pic 9(4).
            02 CurrentMonth-out     pic 99.
            02 CurrentDay-out       pic 99.
    01 RECORDS-PROCESSED.
            02 Filler           pic x(28) value 
                    "Number Of Records Processed:".
            02 num-recs         pic 9(3)   value 0.
            02 Filler           pic x(15) value spaces.
    01 AVERAGE-PROCESSED.
            02 Filler           pic x(9)  value
                    "Average: ".
            02 num-nonzero      pic 9(4) value 0.
            02 Filler           pic x(42) value spaces.
            02 BedroomAverage-out pic zz9.99.
            02 Filler           pic x(5) value spaces.
            02 BathroomAverage-out pic zz9.99.
            02 Filler           pic x(18) value spaces.
            02 SqFtAverage-out  pic ZZZZ9.99.
            02 Filler           pic x(4) value spaces.
            02 SalePriceAverage-out pic $ZZZ,ZZ9.99.


    01 The-City-Table.
            02 City-Table occurs 22 times
               indexed by City2-index
               ascending key is City2-code.
                03 City2-code     pic a(15).
                03 Tax-Rate       pic V999.
                 01 row-index pic 9.
                 01 column-index pic 9.
                 01 city-index pic 99 value 1.
    01 Accum-table.
            02 Bed-Accum occurs 6 pic 9(9)v99 value zero.
    01 Accum-table2.
            02 Bed-Accum2 occurs 6 pic 9(9)v99 value zero.
                       02 Bath-Accum2 occurs 3 
                           pic 9(9)v99 value zero.
    01 END-OF-REPORT.
            02 Filler           pic x(13) value
                    "End Of Report".

    01 table-out. 
            02 filler pic x(35) value spaces.
            02 bed-num pic 9 value zero.
            02 filler pic x(7) value spaces.
            02 accum-out pic $ZZZ,ZZZ,ZZ9.99.
    01 table2-out.
            02 filler      pic x(35) value spaces.
            02 bed-num2    pic 9 value zero.
            02 filler      pic x(7) value spaces.
            02 accum2-out  pic $ZZZ,ZZZ,ZZ9.99.
            02 filler      pic x(7) value spaces.
            02 Bath-Accum  pic 9 value zero.
            02 accum3-out  pic $ZZZ,ZZZ,ZZ9.99.


    01 COLUMN-HEADER.
            02 Filler           pic x(7) value "Address".
            02 Filler           pic x(17) value spaces.
            02 Filler           pic x(4)  value "City".
               02 Filler           pic x(10) value spaces.
               02 Filler           pic x(5)  value "Zip".
               02 Filler           pic x(1)  value spaces.
               02 Filler           pic x(5)  value "State".
               02 Filler           pic x(2)  value spaces.
               02 Filler           pic x(4)  value "Beds".
            02 Filler           pic x(1)  value spaces.
            02 Filler           pic x(5)  value "Baths".
            02 Filler           pic x(2)  value spaces.
            02 Filler           pic x(4) value "Prop".
            02 Filler           pic x(6)  value spaces.
            02 Filler           pic x(5) value "Price".
            02 Filler           pic x(2)  value spaces.
            02 Filler           pic x(10) value "Price/Sqft".
            02 Filler           pic x(3)  value spaces.
            02 Filler           pic x(5)  value "Taxes".
            02 Filler           pic x(5)  value spaces.
            02 Filler           pic x(8)  value "Tax-Rate".

    01 INFO-LINE.
            02 PropertyAddress-out      pic x(20).
            02 Filler           pic x(1)  value spaces.
            02 City-out         pic a(15).
            02 Filler           pic x(1) value spaces.
            02 Zip-out          pic 9(6).
            02 Filler           pic x(2) value spaces.
            02 State-out        pic a(2).
            02 Filler           pic x(5) value spaces.
            02 Bedrooms-out         pic 9.
            02 Filler           pic x(5) value spaces.
            02 Bathrooms-out        pic 9.
            02 Filler           pic x(3) value spaces.
            02 PropertyType-out     pic x(8).
            02 Filler           pic x(2)  value spaces.
            02 SalePrice-out    pic 9(6).
            02 Filler           pic x(1) value spaces.
            02 PriceSqFtT-out   pic $ZzZ,ZZ9.99.
            02 Filler           pic x(1) value spaces.
            02 Taxes-out        pic $zzz,zz9.99.
            02 Filler           pic x(1) value spaces.
            02 Tax-Rate1-out    pic $zz,zz9.99.
    01 TEMP-VAR.
            02 PriceSqFtT       pic 9(5)v99 value zero.
            02 PriceSqFtAccum   pic 9(6)v99 value zero.
            02 BedroomAverage   pic 9(4)v99 value zero.
            02 BathroomAverage  pic 9(4)v99 value zero.
            02 SqFtAverage      pic 9(6)v99 value zero.
            02 SalePriceAverage pic 9(9)v99 value zero.
            02 Taxes            pic 9(7)v99 value zero.
            02 bedtotal         pic 9(4)v99 value zero.
            02 bathtotal        pic 9(4)v99 value zero.
            02 sqfttotal        pic 9(6)v99 value zero.
            02 salepricetotal   pic 9(9)v99 value zero.
            02 temp-tax         pic 9(7)v99 value zero.
            02 row-index1       pic 99 value 1.
            02 column-index1    pic 99 value 1.

    01 eof-flag2                pic x(3) value "No".
    01 eof-flag                 pic x(3) value "No".
        88 End-Reached          value "yes".
    01 invalid-flag             pic x(3) value "No".
        88 Bad-Record           value "yes".
    01 eop-flag   pic x(3) value "No".
        88 page-end             value "yes". 
    01 page-footer.
           02 Filler pic x(60) value spaces.
           02 page-num    pic 9 value 1.
    01 blank-line         pic x(132) value spaces.             

    PROCEDURE DIVISION.
    0000-MAIN-LOGIC.
            Perform 1000-init.
            Perform 2000-main-loop until end-reached.
            Perform 3000-finish.
            stop run.

    1000-init.
            open input input-file input-file2
            output output-file error-file.
            write output-rec from Report-Header.
            write output-rec from Current-Date.
            ACCEPT Current-Date FROM DATE YYYYMMDD.
            write output-rec from Column-Header.
            Read input-file2 at end move "yes" to eof-flag2.
            perform 1010-Load-Table until city-index > 22.
            Read input-file at end move "yes" to eof-flag.

    1010-Load-Table.

            move input-rec2 to city-table(city-index).
            add 1 to city-index. 
            read input-file2 at end move "yes" to eof-flag2.

    1999-Page-End.
            write output-rec from page-footer after
                        advancing 3 lines.
            if not end-reached
               write output-rec from column-header 
                         after advancing page.
            add 1 to page-num.

    2000-main-loop.
            move "no" to eof-flag.
            perform 2100-Validate.
            If Bad-Record 
             perform 2999-error
            else
             perform 2200-process.
            read input-file at end move "yes" to eof-flag.

    2100-validate.
            If not Valid-State or not Valid-Prop or
             Bedrooms not numeric or Bathrooms not
             numeric or SqFT not numeric or
             SalePrice not numeric
              move "yes" to invalid-flag.

    2999-error.
            write error-rec from input-rec.            
            if not valid-state
             move "invalid state" to error-rec
             write error-rec.
            if not Valid-Prop
             move "invalid prop" to error-rec
             write error-rec.
            if Bedrooms not numeric
             move "Bedrooms were not numeric"
             to error-rec
             write error-rec.
            if Bathrooms not numeric
             move "Bathrooms were not numeric"
              to error-rec
             write error-rec.
            if SqFt not numeric
             move "not numeric" to error-rec
             write error-rec.
            if SalePrice not numeric
             move "not numeric" to error-rec
             write error-rec.
            move "No" to invalid-flag.


    2200-process.
            search all city-table
              at end display "No Match"
            when city = city2-code(City2-Index)
              compute temp-tax  = salePrice * Tax-Rate(City2-Index).
            move temp-tax to tax-rate1-out. 
            move PropertyAddress to PropertyAddress-out.
            move City to City-out.
            move Zip to Zip-out.
            move State to State-out.
            move Bedrooms to Bedrooms-out.
            move Bathrooms to Bathrooms-out.
            move PropertyType to PropertyType-out.
            move SalePrice to SalePrice-out.
  **move '12ABCDEF34GHIJKL5MNOPQR' TO The-City-Table.
  **perform 1000-init VARYING I FROM 1 by 1 until I > 3
  **STOP RUN.


            divide SalePrice by sqFt giving PriceSqFtT.
            Add SalePrice to  PriceSqFtAccum.
            Move PriceSqFtT to PriceSqFtT-out.
            add 1 to num-recs.
            If sqft = 0
              Move 0 to PricesqftT.
            if sqft not = 0 
                 add 1 to num-nonzero.
            IF city EQUALS "SACRAMENTO" and Bedrooms >= 2

               compute Taxes = salePrice * .075.
            IF city EQUALS "SACRAMENTO" and Bedrooms < 2 
               MULTIPLY salePrice by .065 giving Taxes.
            IF city NOT EQUAL "SACRAMENTO"
               MULTIPLY salePrice  by .06 giving Taxes.

            IF bedrooms > 0
               add saleprice to bed-accum(bedrooms).
             IF bedrooms > 0
               add saleprice to bed-accum2(bedrooms).


            move Taxes to Taxes-out.
            add Bedrooms to bedtotal.
            add Bathrooms to bathtotal.
            add SqFt to sqfttotal.
            add SalePrice to salepricetotal.
            divide Bedtotal by num-nonzero giving BedroomAverage.
            divide Bathtotal by num-nonzero giving BathroomAverage.
            divide sqfttotal by num-nonzero giving SqFtAverage.
            divide salepricetotal by num-recs giving
            SalePriceAverage.
            move BedroomAverage to BedroomAverage-out.
            move BathroomAverage to BathroomAverage-out.
            move SqFtAverage to SqFtAverage-out.
            move SalePriceAverage to SalePriceAverage-out.
            write output-rec from info-line
                       at eop perform 1999-page-end.

    3000-finish.
            write output-rec from average-processed.
            write output-rec from Records-processed.
            perform 3200-check.
            perform 3100-table varying row-index1
                  from 1 by 1 until row-index1 > 6.
            perform 3200-check.
            perform 3150-table2 varying row-index1
                  from 1 by 1 until row-index1 > 6
                  after column-index from 1 by 1 until
                  column-index > 3.
            perform 3200-check.
            write output-rec from END-OF-REPORT.
            close input-file output-file error-file.

    3100-table.
            move row-index1 to bed-num.
            move bed-accum(row-index1) to accum-out.
            write output-rec from table-out.
     3150-table2.
            move row-index1 to bed-num2.
            move column-index to Bath-accum.
            move bed-accum2(row-index1) to accum2-out.
            move Bath-Accum2(column-index1) to accum3-out.
            write output-rec from table2-out.
     3200-check.
           if not page-end
             perform 3250-blanks until page-end.
           if page-end
             perform 1999-page-end.
           move "no" to eop-flag.

     3250-blanks.
           write output-rec from blank-line
                  at eop move "yes" to eop-flag.                

输出表:

纠正一维:

                               1       $    454,852.00
                               2       $  5,285,635.00
                               3       $ 19,120,759.00
                               4       $ 12,888,340.00
                               5       $  4,544,850.00
                               6       $  1,112,400.00




























                                                        6

不正确的二维:

                               1       $    454,852.00       1$          0.00
                               1       $    454,852.00       2$          0.00
                               1       $    454,852.00       3$          0.00
                               2       $  5,285,635.00       1$          0.00
                               2       $  5,285,635.00       2$          0.00
                               2       $  5,285,635.00       3$          0.00
                               3       $ 19,120,759.00       1$          0.00
                               3       $ 19,120,759.00       2$          0.00
                               3       $ 19,120,759.00       3$          0.00
                               4       $ 12,888,340.00       1$          0.00
                               4       $ 12,888,340.00       2$          0.00
                               4       $ 12,888,340.00       3$          0.00
                               5       $  4,544,850.00       1$          0.00
                               5       $  4,544,850.00       2$          0.00
                               5       $  4,544,850.00       3$          0.00
                               6       $  1,112,400.00       1$          0.00
                               6       $  1,112,400.00       2$          0.00
                               6       $  1,112,400.00       3$          0.00

组项目不能包含 PICture 子句。

你有这个:

   01 Accum-table2.
     02 Bed-Accum2 occurs 6 pic 9(9)v99 value zero.
          03 Bath-Accum2 occurs 3 
              pic 9(9)v99 value zero.

不会编译。

您可能打算这样:

   01 Accum-table2.
     02 Bed-Accum2 occurs 6.
          03 Bath-Accum2 occurs 3 
              pic 9(9)v99 value zero.

这将允许最多六间卧室和最多三间浴室的值。请记住,豪华的六居室 属性 可以很容易地拥有八个或更多浴室,具体取决于您如何定义浴室:-)

作为初学者,您可能需要重新考虑您的代码中的许多方面:

范围分隔符的使用:您正在使用 full-stop/period 来分隔范围。在 1985 COBOL 标准之前,这是划定范围的唯一方法。 1985 年的标准引入了一系列明确的 scrop 定界符,如 END-IF 和 END-READ,并大大放宽了 PROCEDURE DIVISION 中所需的 full-stops/periods 的数量。我强烈建议使用显式范围分隔符代替 full-stops/periods 并放弃在每一行上常规使用 full-stop/period。

缩进:注意并与此保持一致。在定义数据时,通常的做法是在您使用的级别编号中保留 "gaps",这样就可以更改结构而无需重新编号几乎所有内容。

88s 和 SET:您使用 88s,给它们与 MOVE 值相关的字段,并为那些与 88s 本身不接近的字段使用名称。改进这一点的最简单方法是使用 SET 88-name TO TRUE,并建立另一个 88 明确否定它,并在你想关闭标志时将其设置为 TRUE。

Paragrpah-numbering:作为初学者,请在程序完成后执行。然后您可以移动段落而无需重新编号。

对现有值的依赖:小心使用上次执行代码时恰好具有您想要的值的东西。在之前设置该数据所需的所有内容,而不是处理最后一个数据之后。很难发现这一点。