我的循环语法错误,但不会在COBOL中引发错误 [英] Bad syntax with my loop, but not throwing an error in COBOL

查看:92
本文介绍了我的循环语法错误,但不会在COBOL中引发错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我在搞乱开关时搞砸了,想弄清楚为什么它不起作用。它仅读取数据的第一行,然后结束。 (它会打印标题,第一行数据,所有300条处理记录中的所有计算,并为结束报告做最后的标题。

 文件控制
选择F01-输入文件分配给'I:\COBOL\EmployeePay.dat'
组织是按行顺序排列的。

选择分配给'I:\COBOLSIGNEmployeePay.out'的F02-PRINT-FILE文件
组织是行顺序的。

数据分区。
文件段。

FD F01输入文件
记录包含30个字符
数据记录为F01-INPUT-RECORD

01 F01-INPUT-RECORD。
05 F01-员工名称PIC X(18)。
05 F01-员工-SSN PIC 9(9)。
05 F01-GROSS-PAY PIC 9(3)。

FD F02打印文件
记录包含86个字符
数据记录为F02打印线记录
01 F02打印线记录图十(86)。

工作存储部分。

01 W01-DATA-REMAINS-SWITCH PIC X值 Y。

01 W02-DETAIL-LINE。
05 PIC X(2)值空间。
05 W02-员工名称PIC X(18)。
05 PIC X(2)值空间。
05 W02-员工-SSN图片9(9)。
05 PIC X(7)值空间。
05 W02-PAY-100S PIC 9.
05 PIC X(5)值空间。
05 W02-PAY-50S PIC 9.
05 PIC X(4)值空间。
05 W02-PAY-20S PIC 9.
05 PIC X(4)值空间。
05 W02-PAY-10S PIC 9.
05 PIC X(4)值空间。
05 W02-PAY-5S PIC 9.
05 PIC X(4)值空间。
05 W02-PAY-1S PIC 9.
05 PIC X(3)值空间。
05 W02-GROSS-PAY图片9(3)。
05 PIC X(15)。

01 W02-HEADER-LINE1。
05 PIC X(22)值空间。
05 PIC X(24)值空间。
05 PIC X(40)值空间。

01 W02-HEADER-LINE2。
05 PIC X(2)值空间。
05 PIC X(13)值员工姓名。
05 PIC X(20)值空间。
05 PIC X(4)值'$ 100'。
05 PIC X(3)值空间。
05 PIC X(3)值 $ 50。
05 PIC X(2)值空间。
05 PIC X(3)VALUE'$ 20'。
05 PIC X(2)值空间。
05 PIC X(3)VALUE'$ 10'。
05 PIC X(3)值空间。
05 PIC X(2)值'$ 5'。
05 PIC X(3)值空间。
05 PIC X(2)值'$ 1'。
05 PIC X(3)值空间。
05 PIC X(3)值'PAY'。
05 PIC X(15)值空间。

01 W02-CLOSING-LINE。
05 PIC X(13)VALUE报告结束。
05 PIC X(73)值空间。

01 PAY PIC 999V99。

程序部门。

执行100个打开文件。
执行200次写标题行。
执行300个过程的记录
直到W01-DATA-REMAINS-SWITCH ='N'。
执行400次写入。
执行500个关闭文件。

100个打开文件。
打开输入F01-输入文件
输出F02-打印文件
读取F01-输入文件
结束时将 N移动到W01-数据保留开关


200写标题行。
将W02-HEADER-LINE1移至F02-PRINT-LINE-RECORD。
写F02-打印线记录。
将W02-HEADER-LINE2移至F02-PRINT-LINE-RECORD。
写F02-打印线记录。


300个过程记录。

将F01-雇员名称移动到W02-雇员名称。
将F01-EMPLOYEE-SSN移至W02-EMPLOYEE-SSN。
将F01-GROSS-PAY移至W02-GROSS-PAY。

执行310次计算。

将W02-DETAIL-LINE移至F02-PRINT-LINE-RECORD。
写F02-打印线记录。
读取F01-INPUT-FILE
在结束时移至W01-DATA-REMAINS-SWITCH
END-READ。

310-计算。
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 =支付-(W02-PAY-50S * 50)
COMPUTE W02-PAY-20S = PAY / 20
COMPUTE 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 =付款-(W02-PAY-5S * 5)
COMPUTE W02-PAY-1S = PAY / 1


400写脚。

将W02-封闭线移动到F02-PRINT-LINE-记录。
写F02-打印线记录。


500个关闭文件。
关闭F01-输入文件
F02-打印文件。

计算必须在那儿,我知道用法只是数学上的问题继续,他们现在正在工作。 =)



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

解决方案

您正遭受直接插入的困扰



我很快会介绍一下,但首先介绍其他一些内容。



您的标题:我的循环语法不正确,但不会在COBOL中引发错误。我的问题建议是最后写两个标题,这样您就更有可能避免这个问题。没有语法问题,编译器也无济于事。



其次,您的问题描述:我的读取循环遇到麻烦,它将不会继续循环。



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



<这的重要性如下:如果对现有代码的解释不能完全获得所获得的输出,那么这肯定不是对问题的完整解释:在知道完整代码之前不要更改代码行解释。



好吧,但是通常您需要进行一些更改以帮助确定问题,或者只是戳一下,希望会发生一些魔术和问题。将被修复。好吧,不要对原始程序执行此操作。复制程序。如果您想这样做,我们不想指出您尝试过的bodges和hacks的副作用。



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



有时问题是一个空文件,或者只有一个记录的文件,或者实际上是一个损坏的文件(提示它要开张,第三次要跳水)。如果您不包括样本数据,那么除了它们不太可能之外,我们如何排除这些数据呢?



然后我们需要查看无效的代码。但是,如果您知道那是行不通的,最有可能找到答案。因此,您必须尽最大努力将代码缩减到仍然存在问题的最小数量。



一个好标题,一旦问题完成就定下来;准确的问题陈述;样本输入数据,实际输出,预期输出;错误消息(完整,带有错误代码)(如果有);



通常,在很好地准备好问题后,无论如何,您甚至都可以自己回答,甚至不需要提出问题。



一个好方法是向他人解释您的问题。通过阅读和口语,您将学到的不仅仅是阅读(自己)和假设。即使您没有同事/朋友,也可以假装自己有Cardboad-Cutout编程器(可以是充气式编程器,就像喜剧电影中的自动驾驶仪一样),鸡蛋杯或橡皮鸭(显然是这样)



哦,我将更新您的另一个问题的答案。



因此,就是掉线或掉线。

 移动X到Y 

some-paragraph-name。
从A移到B
...

在那里您看到一个段落名称。控件如何直接传递到段落名称之后的行?普通代码(非声明性代码,非SORT程序)有三种有效,合法和可用的方法:执行MOVE X之后,如果代码不在PERFORM范围内以 some-paragraph-name结尾的PERFORM中,则MOVE A将是下一个;转到某段名称;



(请注意,适用于以上各段的内容同样适用于程序部分的各节)。

>

这与许多其他语言一样,功能或子例程将被保护起来免受主要代码流的影响,它们不能落入



在COBOL中,到达该位置的所有三种方法都是完全有效的,并且即使对于同一程序中的相同段落名称也完全有效(有效当然不是良好实践:良好实践会排除这种使用)。



由于所有方法都是完全有效的,因此



这是您的问题:

p>

 执行500个关闭文件。 

100个打开文件。

我突出显示了该行,不幸的是,由于该行没有显示任何内容

 执行500个关闭文件
GOBACK(或STOP RUN或EXIT PROGRAM,但是GOBACK更好)

100个打开文件。

因此,您的程序正在运行,一次处理整个输入文件一条记录,然后写入数据到输出文件,一次记录。一切都差不多。



然后关闭文件。



然后进入100-OPEN-FILES ,并 BANG! 删除您的输出。然后进行第一次读取。然后执行300次(仅一次),因此在读取下一条记录之前先处理一条记录,然后依次进入310-,400-,然后500-,这将关闭文件并退出程序的结尾,从而使执行停止。



实际上,取决于编译器,程序中应该至少有一个终止语句,并且从该程序中退出失败。但是,您使用的编译器不会执行此操作(或者您已告诉它不要使用选项/开关执行操作。)。



添加GOBACK / STOP RUN / EXIT PROGRAM,您的程序将运行。通常。



您怎么能自己发现这个?计数输入和输出记录并在程序结束时显示总数通常会有所帮助。如果您使用FILE STATUS,就不太会怀疑它是一个狡猾的文件。格式很好,使用了88s,就像Bruce已经建议的那样。


I guess i messed the switch up when i was messing with it trying to figure out why it woulden't work. It only reads the first line of my data, then ends. ( it prints headers, first line of data, all the calculations that are in 300-process-records, and does the final heading for ending the report.

       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.

The computes had to be there, i understood the usage it was just a math thing that i was stuck on, theyre working now. =)

So maybe i misunderstood your answer, but fixing it didnt change anything. It still only returns with one line of data from the file and ends.

解决方案

You're suffering from "drop-through" or "fall-through".

I'll go into that shortly, but first a few other things.

Your title: Bad syntax with my loop, but not throwing an error in COBOL. My advice for questions is two write the title last, then you are more likely to avoid this problem. There is no "syntax" issue and nothing for the compiler to assist you with.

Secondly, your problem description: "Having some trouble with my read loop, it will not continue through the loop."

The meaning of that is unclear. We read one meaning into it (the loop does not get entered at all) and you meant another (one record only, the first on the file, appears in the output).

The importance of this is as follows: if the explanation of the existing code does not exactly obtain the output achieved, then that is certainly not a full explanation of the problem: don't change a line of code until you know the full explanation.

Well, OK, but often you want to make some change to aid problem determination, or just to poke about in the hope that some magic will happen and the problem will be fixed. Well, don't do it to the original program. Copy the program. We don't want to be pointing out the side-effects of the bodges and hacks you've attempted, if you want to do that.

On our reading, the Y/Y and N/N problem explained what (we thought) you were getting. However, it does not explain the actual output. How would we know that? You haven't included any output.

Sometimes the problem is an "empty" file, or a file with only one record, or indeed a "corrupt" file (tip it a fiver and it'll take a dive in the third). How, other than their being unlikely, do we exclude those if you don't include sample data?

Then we need to see the code that isn't working. However, if you knew what it was that wasn't working, most likely you'd get to the answer. So, you have to do your best to pare down the code to the smallest amount which still exhibits the problem.

So, a good title, finalised once the question is complete; accurate problem statement; sample input data, actual output, expected output; error messages (in full, with error-codes) if any; minimal sample code which produces the problem.

Often, in the good preparation of a good question you'll get to the answer yourself anyway, before you even need to ask.

A good way is to explain your problem to someone else. Reading and speaking you will read more than simply reading (to yourself) and assuming. Even if you have no colleague/friend available, just pretend you have a Cardboad-Cutout Programmer (can be an inflatable one, like the autopilot always is in comedy films), or an egg-cup, or a rubber-duck (apparently this one works as well).

Oh, and I'll update my answer on your other question.

So, the "fall-through" or "drop-through".

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

There you see a paragraph name. How does control pass to the line immediately after the paragraph name? There are three valid, legal and usable ways for ordinary code (non-Declaratives, non-SORT-procedure): after MOVE X is executed, if the code is not within a PERFORM whose range finishes at "some-paragraph-name" then the MOVE A will be next; a GO TO some-paragraph-name; a PERFORM (in some variation) of some-paragraph-name.

(Note, what applies to paragraphs above applies equally to SECTIONs in the PROCEDURE DIVISION).

This is not like many other languages where a "function" or a "sub-routine" would be "protected" from the main flow of code, they could not be "fallen into" or GO TO'd.

In COBOL, all three methods of getting there are entirely valid, and entirely valid even for the same paragraph-name in the same program (valid doesn't, of course, mean good practice: good practice would preclude such use).

Since all methods are entirely valid, the compiler has nothing to say when you use one of the methods, even when its use was unintended (how would the compiler know that?).

Here's your problem:

PERFORM 500-CLOSE-FILES.

100-OPEN-FILES.

I've highlighted the line, unfortunately since there is nothing on the line it doesn't show up.

    PERFORM 500-CLOSE-FILES
    GOBACK (or STOP RUN, or EXIT PROGRAM, but GOBACK is better)
    .
100-OPEN-FILES.

So, your program was running, processing the entire input file a record at a time, writing the data to the output file, a record at a time. All approximately OK.

Then you closed the files.

Then you dropped through to 100-OPEN-FILES, and BANG! your output is wiped. Then it does the first read. Then does 300-, just the once, so processing one record before reading the next, then drops into 310-, then 400-, then 500- which closes the files and falls off the end of the program, bringing execution to a halt.

Depending on compiler, actually, there should have been at least one termination statement in the program and a failure on falling off the program. However, the compiler you are using doesn't do that (or you've told it not to do it with options/switches).

Add the GOBACK/STOP RUN/EXIT PROGRAM and your program will work. Generally.

How could you have spotted this yourself? Counting the input and output records and DISPLAYing the totals at the end of the program often helps. If you use the FILE STATUS you get less suspicious of it being a dodgy file. Good formatting, use of 88s, as Bruce already suggested.

这篇关于我的循环语法错误,但不会在COBOL中引发错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆