2014-09-27 82 views
0

当我试图将输出写入文件时,COBOL中有一个错误代码18。我正在使用Micro Focus VS 2012.我尝试了一切,但是目前似乎不能正确打印输出。COBOL错误代码18

... 
    ENVIRONMENT DIVISION. 
    INPUT-OUTPUT SECTION. 
    FILE-CONTROL. 

     SELECT GRADE-FILE ASSIGN TO 'Grades.txt'. 

     SELECT PRINT-FILE ASSIGN TO 'Output.txt' 
     ORGANIZATION IS LINE SEQUENTIAL. 


    DATA DIVISION. 
    FILE SECTION. 
    FD GRADE-FILE 
     LABEL RECORDS ARE STANDARD. 
    01 GRADE-RECORD. 
     05 I-STUDENT PIC X(14). 
     05 I-GRADE1 PIC 999. 
     05 I-GRADE2 PIC 999. 
     05 I-GRADE3 PIC 999. 
     05 I-GRADE4 PIC 999. 
     05 I-GRADE5 PIC 999. 
     05 I-GRADE6 PIC 999. 

    FD PRINT-FILE 
     LABEL RECORDS ARE STANDARD. 
    01 PRINT-RECORD PIC X(80). 


    WORKING-STORAGE SECTION. 
    01 PROGRAM-VARIABLES. 
     05 W-AVERAGE PIC 999V99. 
     05 W-EOF-FLAG PIC X VALUE 'N'. 

    01 PAGE-TITLE. 
     05 PIC X(46) VALUE 
     ' S I X W E E K G R A D E R E P O R T'. 

    01 HEADING-LINE1. 
     05 PIC X(51) VALUE 
     ' Student  T e s t S c o r e s Average'. 

    01 HEADING-LINE2. 
     05 PIC X(51) VALUE 
     '--------------------------------------------------'. 

    01 DETAIL-LINE. 
     05     PIC X VALUE SPACE. 
     05 O-STUDENT   PIC X(14). 
     05     PIC X VALUE SPACE. 
     05 O-GRADE1   PIC ZZ9. 
     05     PIC X VALUE SPACE. 
     05 O-GRADE2   PIC ZZ9. 
     05     PIC X VALUE SPACE. 
     05 O-GRADE3   PIC ZZ9. 
     05     PIC X VALUE SPACE. 
     05 O-GRADE4   PIC ZZ9. 
     05     PIC X VALUE SPACE. 
     05 O-GRADE5   PIC ZZ9. 
     05     PIC X VALUE SPACE. 
     05 O-GRADE6   PIC ZZ9. 
     05     PIC X(4) VALUE SPACE. 
     05 O-AVERAGE   PIC ZZ9.99. 

    PROCEDURE DIVISION. 
    10-MAINLINE. 
     OPEN INPUT GRADE-FILE 
      OUTPUT PRINT-FILE 
     PERFORM 20-PRINT-HEADINGS 
     PERFORM 30-PROCESS-LOOP 
     CLOSE GRADE-FILE 
      PRINT-FILE 
     STOP RUN. 

    20-PRINT-HEADINGS. 
     MOVE PAGE-TITLE TO PRINT-RECORD 
     WRITE PRINT-RECORD AFTER ADVANCING 1 LINE 
     MOVE HEADING-LINE1 TO PRINT-RECORD 
     WRITE PRINT-RECORD AFTER ADVANCING 3 LINES 
     MOVE HEADING-LINE2 TO PRINT-RECORD 
     WRITE PRINT-RECORD AFTER ADVANCING 1 LINE. 

    30-PROCESS-LOOP. 
    * PERFORM 40-READ-RECORD 
     READ GRADE-FILE 
     PERFORM UNTIL W-EOF-FLAG = 'Y' 
      PERFORM 50-COMPUTE-GRADE-AVERAGE 
      PERFORM 60-PRINT-DETAIL-LINE 
      READ GRADE-FILE 
    *  PERFORM 40-READ-RECORD 
     END-PERFORM. 

    *40-READ-RECORD. 
    * READ GRADE-FILE 
    *  AT END MOVE 'Y' TO W-EOF-FLAG. 

    50-COMPUTE-GRADE-AVERAGE. 
     COMPUTE W-AVERAGE ROUNDED = (I-GRADE1 + I-GRADE2 + I-GRADE3 + I-GRADE4 + I-GRADE5 + I-GRADE6)/6. 

    60-PRINT-DETAIL-LINE. 
     MOVE SPACES TO DETAIL-LINE 
     MOVE I-STUDENT TO O-STUDENT 
     MOVE I-GRADE1 TO O-GRADE1 
     MOVE I-GRADE2 TO O-GRADE2 
     MOVE I-GRADE3 TO O-GRADE3 
     MOVE I-GRADE4 TO O-GRADE4 
     MOVE I-GRADE5 TO O-GRADE5 
     MOVE I-GRADE6 TO O-GRADE6 
     MOVE W-AVERAGE TO O-AVERAGE 
     WRITE PRINT-RECORD FROM DETAIL-LINE AFTER ADVANCING 1 LINE. 

    end program "GradeReport.Program1" 

S I X W E E K G R A D E R E P O R T 


Student  T e s t S c o r e s Average 
-------------------------------------------------- 
KellyAntonetz0 700 500 980 800 650 852 747.00 
obertCain09708 207 907 309 406 2;1 25> 400.67 
Dehaven0810870 940 850 930 892 122 981 785.83 
rmon0760770800 810 750 92; 142 9>1 <1> 816.33 
g0990930890830 940 901 =1> 41= ?82 65 872.50 
06707108408809 6=9 ;52 565 <<0 900 870 924.33 
78052076089Woo 493 9>4 520 760 760 830 734.50 
+1

这将是很好的指定错误发生的地方,例如在OPEN或WRITE中?也使用FILE STATUS,对输入和输出分别打开OPEN并查看错误18在编译器中的含义。 – NoChance 2014-09-27 06:24:39

+1

您不显示样本输入数据。第一行输出中的'z0'是可疑的 - 如果我是你,我会查看你的文件组织。报告主体中的“数字”数据应该给你一个线索。有一位名叫'obert ...'的学生很不寻常,这表明你的输入数据没有被正确读取 - 从那里开始,它就是GIGO。您似乎正在从具有可变长度数据记录的文件中读取固定长度的记录。 – Magoo 2014-09-27 06:50:41

+0

EmmadKareem的建议很好,Magoo发现了一些关键。你需要显示你的输入记录。看起来应该将名字的前两个元素分隔在第一个记录上的空间不知何故(缺少COBOL),正如名字中的其他空格一样。您的输入数据长度可变,影响名称字段,并导致您的所有其他字段向左“拉”。在COBOL计划之前,“某事”已经占据了你名字的所有空间。 – 2014-09-27 09:09:26

回答

2

在您的COBOL程序之前的某些东西通过删除所有空格并将数据移动到左侧来清理文件。

你的第一个学生显示为KellyAntonetz,但可能应该是Kelly Antonetz。由于只有一个空间被删除,因此等级数据只向左移动了一个位置,所以数字仍然可以识别,虽然平均数是10的因子,但它大致正确。

由于跟在85之后,它实际上并不正确(除了10的幂)。 2从哪里来的?

它来自下一个记录,其中第一个名字应该是罗伯特,但你显示为obertCain09708。字母R的ASCII码是X'82'。当被COBOL视为数字时,8将被忽略(或者在数字的尾部字节中时会导致崩溃)。您的编译器不会导致代码崩溃,但会将R视为数字2

obertCain只有14个字节中的名称。这次“丢失”的五个空格/空白导致数字被左移五个字节。从这一点开始,解释你展示的输出如何符合推测的输入,只能成为一种学术活动。

进一步支持,是这将是从微距对焦编译器18的文件状态码,这里的引用:http://www.simotime.com/vsmfsk01.htm

它说,为18

Read part record error: EOF before EOR or file open in wrong mode (Micro Focus).

你的最终战绩会“完成“之前,在读取32个字节之前检测到文件结束。

请注意,错误在您的输入文件,而不是您的输出文件。

以这种方式丢失空格可以通过很多方式完成,所以我无法在文件到达COBOL程序之前猜到你对文件做了什么,但COBOL本身和你的代码都没有这样做。

记下Emmad Kareem的评论。使用FILE STATUS。在每个IO之后检查文件状态字段(每个文件定义一个字段),以便知道问题何时发生以及问题是什么。

在正在读取的文件上测试文件状态字段为10时,会得到比READ上的AT END更干净的代码。

请注意,如果你的程序没有在那里崩溃,它会无限循环或不久后崩溃。可能在试图解决您的问题时,您已经评论了您对“阅读段落”的使用,并且该段落是您设置文件结束的唯一位置。

如果您使用文件状态而不是AT END,则不需要定义标志/开关,您可以在文件状态字段上使用88,并让COBOL运行时直接为您设置它,而不必编码。

只是关于您的详细信息线的几点。

当你移动到每个命名字段,并且(未命名)FILLER具有VALUE SPACE时,没有必要使用MOVE SPACE

你不需要必需需要(未命名)FILLERS。试试这个:

01 DETAIL-LINE. 
     05 O-STUDENT   PIC BX(14). 
     05 O-GRADE1   PIC ZZZ9. 
     05 O-GRADE2   PIC ZZZ9. 
     05 O-GRADE3   PIC ZZZ9. 
     05 O-GRADE4   PIC ZZZ9. 
     05 O-GRADE5   PIC ZZZ9. 
     05 O-GRADE6   PIC ZZZ9. 
     05 O-AVERAGE   PIC Z(6)9.99. 

如果你使用COBOL,你可能会看到这种类型的东西,所以很高兴知道。大量的输出可能会导致性能下降。您可能会发现将“排队”输出到标题更方便。

啊。把你的输入文件不使用LINE SEQUENTIAL,我预测你有一个在脚本运行一段时间之前运行一段时间的脚本,它应该在每个脚本的末尾删除记录终止符(无论你的操作系统上有哪些)逻辑记录,但是您意外地从记录的所有位置中删除了全部whitespace

使用LINE SEQUENTIAL您可以拥有固定长度的记录,这些记录恰好也是“终止”的。除非练习特别包括删除记录终止符,否则只需使用LINE SEQUENTIAL

如果您应该删除终结符,则不要这样做,因为whitespace涵盖的内容太多(具体而言),也会将更改“锚定”到记录结尾。