对于作为COBOL课程一部分的作业,我的输入文件是一个名为BRANCHTOT.SEQ的顺序文件,包含两种类型的记录:
第一个是我所称的头记录,它说明文件中记录的总数(不包括头记录本身)。这只是一项记录。
如果这是文件中唯一的记录,我将将其定义为:
01 header-record.
03 record-count PIC 9(6).
03 FILLER PIC X(13). 第二种类型的记录是我必须读取和处理输出的记录。其结构如下:
01 sales-record.
03 branch-nr PIC X(5).
03 office-nr PIC 9(2).
03 count PIC 9(5).
03 sum PIC 9(5)V99.我习惯于处理带有一种记录的文件。
任务比我在这里描述的要复杂得多,但是对于问题的这一部分,我的程序必须读取和处理销售记录记录,并打印它读取的这些记录的总数,并将其与标头记录中列出的数量进行比较。如果两者不匹配,我需要在输出列表中有一个语句来注意这个错误。
发布于 2016-01-12 14:01:17
如果您定义了这两个记录,您就可以在单个FD下完全按照您已经显示的那样做。这将给您一个隐含的重新定义。
在文件的SELECT语句上使用文件状态(始终)。始终检查文件状态字段是否获得期望值.使用88条件名作为值"10“来标识文件结束。不要使用AT END/NOT AT END。
请注意,您不能在练习中完美地完成这个任务,因为文件没有被正确定义。没有标识头记录或数据记录的可用指示。唯一的指示是“头是第一位的,其余的都是数据”。这似乎很好,但当有人最初对编写文件的程序进行腌制,而没有给出标题或两个或两个以上的头时,就会转向slok。
如果一个文件有一个结构,那么这个结构应该在数据中,因为它可以被检查。处理一个糟糕的文件,就好像它是一个好的文件一样,可能会非常昂贵。也很尴尬。
此外,您还需要知道文件是否允许为“空”。由于它有一个头记录,一个“空”文件应该包含一个具有零数据记录计数的头记录。您的情况可能有所不同,因为文件不是设计的。
在您的初始处理中(在输入文件被OPEN编辑之后),您将读取第一个记录。如果是这样的话,处理“空文件”。检查它是一个标题。把记录存起来。
然后你读下一张唱片。你检查它不是标题。
然后你处理你的数据,记住你有第一个可用的数据记录。
Loop until end-of-input
process record
read next record
End-Loop在文件结束时(循环结束时),您将检查标题上的记录数(从存储的值)到所读取的数据的数量(在记录的处理中计数)。
一旦你有了你的程序,你就有了一个“模型”来建立其他程序。你只需要得到一般的“这是我处理一个文件的方式”更正一次,然后使用它作为你的下一个文件处理程序的起点。下一个程序会更复杂,所以您将得到另一个模型。
过了一段时间,您将有大约五个模型,每个模型都基于来自一个简单任务的工作代码。
我反对使用AT END/NOT AT END来读取文件有几个原因:
复杂性和可理解性
a-pargraph-for-SO-formatting.
PERFORM priming-read
PERFORM
UNTIL end-of-infile
PERFORM process-data
PEFORM read-next
END-PERFORM
.
priming-read.
PERFORM read-next
.
read-next.
READ IN-FILE
IF NOT IN-FILE-STATUS-OK
PERFORM diagnostic-message-and-fail
END-IF
.Vs.
PERFORM UNTIL WS-EOF='Y'
READ STUDENT INTO WS-STUDENT
AT END MOVE 'Y' TO WS-EOF
NOT AT END DISPLAY WS-STUDENT
END-READ
END-PERFORM如果不测试WS,就不能在结束读取之后放入任何代码。但人们是这样做的。
可靠性和易用性
如果在SELECT中为一个文件指定了文件状态,那么就由程序员来测试它。如果有什么不对劲,很明显,最终是不正确的,但没有新的记录。随后的阅读将得到同样的情况,一个大脂肪圈接踵而至。因此,应该测试文件状态字段(如果使用了文件状态),那么,为什么不使用文件状态字段来测试文件结束,因为它更简单,而不是在非AT终端中的进一步条件。
当然,如果您不使用文件状态,运行时将处理一些事情,但是以一种广泛而直截了当的方式,没有机会提供更多的诊断信息,
当然,你也可以在.但这进一步复杂化了,许多人都不习惯。
它鼓励使用GO来“摆脱混乱”。
READ IN-FILE
AT END GO TO no-more-records
END-READ为什么在FD下定义记录,为什么不在工作存储中?
或者,READ ...和READ ... INTO ...有什么区别?
FD中的FILE SECTION允许在“记录区域”中描述记录。
对于输入文件,这将是最后一条成功读取的记录。如果有一个。文件的打开将使记录区域可用。一旦遇到文件结束,将不再有当前记录.当文件是CLOSEd时,也不会有当前记录(无论是否到达文件结束)。
这意味着您不应该在文件为OPENed之前访问记录区域,在文件为CLOSEd之后访问记录区域,或者在到达文件结束后访问记录区域。在IBM大型机上,不应该是经常不能的,因为它很容易导致S0C4 abend,这是一个保护异常。输入区域实际上是在处理文件的IO例程中定义的,而不是在COBOL程序中定义的。FD只是将您的定义映射到记录区域的地址。如果当时不存在记录区域,则无法访问它。
对于一个简单的文件结构,您不需要同时访问来自不同记录的数据,您可以始终使用FD。
对于更复杂的结构,您需要存储来自不同记录类型的数据,因为只有当前记录在FD下可用。
您可以存储整个记录,或者只存储您需要的部分。
在读取之后的某个时间点,您可以通过移动单个字段来存储所需的部分。
在读取之后,您可以通过整个记录在FD下的移动来存储整个记录,或者使用READ .变成..。这是自动完成的。
读..。变成..。对输入文件上的每条记录进行移动(隐式)。如果您不需要这样做,这是对资源的浪费,而且由于人们为大型机上的资源(如CPU )付费,除非您迫切需要它,否则值得避免。
网站通常有当地的标准。你遵循这些标准,即使它们不是很好(你试图改变它们,不要总是成功)。如果你被告知使用阅读..。变成..。你用它。
不过,关于信息,我不使用阅读.变成..。(除非在上述情况下),并且从未遇到使用FD和MOVEing的问题--我想要的数据(无论是单个字段,还是整个记录)。
使用FD是“最好的”。除非当地标准另有规定。那么,遵循当地的标准是“最好的”。
请注意,有一些东西可以修改上面的内容,并在程序中为记录创建一个特定的区域。如果进入(从写开始)可以隐式地获取整个记录MOVEd两次。
发布于 2016-01-12 13:41:18
好的,谢谢你的评论,这是一门课程,所以它在风格上是相当免费的。下面是读取文件的一个极好的开端
通常情况下,如果你说到“重新定义”,这意味着你的老师希望你使用一个。所以你的记录应该是这样定义的:
01 my-record.
05 my-header.
10 record-count PIC 9(6).
10 FILLER PIC X(13).
05 my-sales-record redefines my-header.
10 branch-nr PIC X(5).
10 office-nr PIC 9(2).
10 count PIC 9(5).
10 sum PIC 9(5)V99.这是可行的,因为两者都有19个字符长。不需要额外的填料,也不需要复杂的东西。
然后,稍后,你会有一个
READ myfile INTO my-record使用计数器(我希望您知道如何使用简单的数字变量)来计数记录。并使用它来知道它是否是标题:
IF current-record = 1
(do something with the header)
ELSE
(do something with the sales record)
END-IF确保所有这些都嵌入在一个循环中,就像我的示例链接中描述的那样,并且应该可以工作。
https://stackoverflow.com/questions/34742684
复制相似问题