我的循环语法错误,但没有在COBOL

时间:2015-09-30 22:46:41

标签: cobol

我想当我弄乱它时,我弄乱了开关,试图找出它为什么不起作用。它只读取我数据的第一行,然后结束。 (它打印标题,第一行数据,300个进程记录中的所有计算,并完成结束报告的最终标题。

       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.

计算必须在那里,我理解它的使用只是一个数学的东西,我被困住,他们现在正在工作。 =)

所以也许我误解了你的答案,但修理它并没有改变任何事情。它仍然只返回文件中的一行数据并结束。

2 个答案:

答案 0 :(得分:3)

你正在遭受"辍学"或"堕落"。

我很快就会谈到这一点,但首先是其他一些事情。

您的头衔:Bad syntax with my loop, but not throwing an error in COBOL。我对问题的建议是最后写两个标题,然后你更有可能避免这个问题。没有"语法"问题并没有让编译器帮助你。

其次,你的问题描述:"我的阅读循环出现问题,它不会继续循环。"

其含义尚不清楚。我们读了一个含义(循环根本没有输入),你的意思是另一个(仅一个记录,文件中的第一个,出现在输出中)。

这一点的重要性如下:如果对现有代码的解释并没有完全获得输出,那么这肯定不是对问题的完整解释:不要改变代码行直到你知道完整的解释。

好吧,好吧,但是你经常想做一些改变以帮助确定问题,或者只是为了捅一下,希望能发生一些魔法并解决问题。好吧,不要做原始程序。复制程序。如果你想这样做,我们不想指出你所尝试过的副本和黑客的副作用。

在我们的阅读中,Y / Y和N / N问题解释了(我们认为)你得到了什么。但是,它没有解释实际输出。我们怎么知道呢?你还没有包含任何输出。

有时候这个问题是空的"文件,或只有一个记录的文件,或者确实是一个"腐败"文件(给它一个提示,它会在第三个中潜入)。除了不太可能之外,如果您不包含样本数据,我们会如何排除这些内容?

然后我们需要查看不起作用的代码。但是,如果你知道它不起作用的话,你很可能会得到答案。因此,您必须尽力将代码削减到仍然存在问题的最小数量。

所以,一个好的头衔,一旦问题完成就最终确定;准确的问题陈述;样本输入数据,实际输出,预期输出;错误消息(完整,带有错误代码),如果有的话;产生问题的最小样本代码。

通常,在准备好一个好问题时,无论如何,在你甚至需要提问之前,你都会自己找到答案。

一个好方法是向别人解释你的问题。阅读和说话你不仅仅是阅读(给自己)和假设。即使你没有同事/朋友,也只是假装你有一个Cardboad-Cutout程序员(可以是一个充气的,就像自动驾驶仪总是在喜剧电影中),或者一个蛋杯,或一个橡皮鸭(显然这个一个也有效。)

哦,我会在你的另一个问题上更新我的答案。

所以,"堕落"或" drop-through"。

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

在那里你看到一个段落名称。控制如何在段落名称后立即传递到该行?普通代码有三种有效,合法和可用的方法(非声明,非SORT程序):执行MOVE X后,如果代码不在PERFORM中,其范围结束于"某段 - 命名"然后MOVE A将是下一个;转到段落名称;一些段落名称的表现(在某些变体中)。

(注意,适用于上述段落的内容同样适用于程序部分中的章节。)

这与许多其他语言不同,其中"功能"或者"子程序"将受到保护"从代码的主要流程来看,它们不会被淹没在"或转到' d。

在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 / STOP RUN / EXIT PROGRAM,您的程序将正常运行。通常。

你怎么能自己发现这个?计算输入和输出记录并在程序结束时显示总计通常会有所帮助。如果你使用文件状态,你就不会怀疑它是一个狡猾的文件。良好的格式化,使用88s,正如布鲁斯已经建议的那样。

答案 1 :(得分:0)

Two obvious problems:

  1. The read statements2. look to be in the wrong columns
  2. The no loop statement
  3. You need to set W01-DATA-REMAINS-SWITCH to Y before you start

Try

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

Also

  1. Look up 88 levels and the set verb e.g.

    SET EOF            to true
    
  2. Find more out how cobol should be formatted