我对COBOL很陌生,很难在.dat文件中搜索特定的条目。这样做的目的是在其中一个字段中搜索所有具有特定代码的记录。
我试着在google上找到答案,但无论我走到哪里,答案都是不同的,我不知道为什么我不能适应我的问题。
我亦发现这个问题:
但答案并没有详细说明。
这是我的密码:
IDENTIFICATION DIVISION.
program-id. AR AS "A.AR".
environment division.
configuration section.
special-names. DECIMAL-POINT IS COMMA.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ARQ-ATUALIZACAO ASSIGN "C:\temp\atualizacao.dat"
ORGANIZATION IS INDEXED
ACCESS MODE IS SEQUENTIAL
RECORD KEY IS ID-ATUALIZACAO
ALTERNATE RECORD KEY IS COD-RASTREIO
FILE STATUS IS ST-ATUALIZACAO.
data division.
FILE SECTION.
FD ARQ-ATUALIZACAO.
01 REG-ATUALIZACAO.
05 ID-ATUALIZACAO PIC 9(10).
05 COD-RASTREIO PIC X(13).
05 TITULO PIC X(15).
05 DESCRICAO PIC X(30).
05 FILLER PIC X(30).
working-storage section.
01 WS-RECORD.
03 ENTRIES OCCURS 18 TIMES INDEXED BY I.
05 WS-ID PIC 9(10).
05 WS-RAST PIC X(13).
05 WS-TIT PIC X(15).
05 WS-DESC PIC X(30).
77 ARE-THERE-MORE-RECORDS PIC XXX VALUE "YES".
77 NAME-COUNT PIC 99.
77 PROCURA PIC X(13).
77 ST-ATUALIZACAO PIC XX VALUE SPACES.
procedure division.
OPEN INPUT ARQ-ATUALIZACAO
PERFORM UNTIL ARE-THERE-MORE-RECORDS = 'NO '
READ ARQ-ATUALIZACAO
AT END
MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
NOT AT END
PERFORM 300-STORE-NAME
END-READ
END-PERFORM
CLOSE ARQ-ATUALIZACAO.
300-STORE-NAME.
ADD 1 TO NAME-COUNT
MOVE REG-ATUALIZACAO TO ENTRIES OF WS-RECORD(NAME-COUNT).
OPEN I-O ARQ-ATUALIZACAO
DISPLAY "CODIGO DA ENCOMENDA.:" AT 1010
DISPLAY "STATUS:" AT 2433
DISPLAY ST-ATUALIZACAO AT 2440
ACCEPT PROCURA AT 1030 WITH REQUIRED FULL
SEARCH ENTRIES
AT END DISPLAY "CODIGO NAO ENCONTRADO" AT 0210
WHEN WS-RAST(I) = PROCURA
DISPLAY "REGISTROS ENCONTRADOS" AT 0210
DISPLAY WS-RAST(I) AT 0310
DISPLAY WS-ID(I) AT 0410
DISPLAY WS-TIT(I) AT 0510
DISPLAY WS-DESC(I) AT 0610
END-SEARCH
CLOSE ARQ-ATUALIZACAO
EXIT PROGRAM.编辑-我修改了很多代码,所以我会在这里发布新的代码:
IDENTIFICATION DIVISION.
program-id. ATUALIZACAOR AS "ATUALIZACAO.ATUALIZACAOR".
environment division.
configuration section.
special-names. DECIMAL-POINT IS COMMA.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ARQ-ATUALIZACAO ASSIGN "C:\temp\atualizacao.dat"
ORGANIZATION IS INDEXED
RECORD KEY IS ID-ATUALIZACAO
ALTERNATE RECORD KEY IS COD-RASTREIO
ACCESS MODE IS RANDOM
FILE STATUS IS ST-ATUALIZACAO.
data division.
FILE SECTION.
FD ARQ-ATUALIZACAO.
01 REG-ATUALIZACAO.
05 ID-ATUALIZACAO PIC 9(10).
05 COD-RASTREIO PIC X(13).
05 TITULO PIC X(15).
05 DESCRICAO PIC X(30).
05 FILLER PIC X(30).
working-storage section.
01 ST-ATUALIZACAO PIC XX.
88 end-of-input-file VALUE "10".
88 INPUT-FILE-OK VALUE ZERO "10".
77 PROCURA PIC X(13).
77 RESP PIC X VALUE SPACE.
procedure division.
INICIO.
PERFORM WITH TEST AFTER UNTIL RESP = "N"
DISPLAY "CODIGO DA ENCOMENDA.:" AT 1010 ERASE SCREEN
DISPLAY "STATUS:" AT 2433
DISPLAY ST-ATUALIZACAO AT 2440
ACCEPT PROCURA AT 1030 WITH REQUIRED FULL
OPEN I-O ARQ-ATUALIZACAO
PERFORM priming-READ-input-file
PERFORM
UNTIL end-of-input-file
PERFORM process-input
PERFORM READ-input-file
END-PERFORM
DISPLAY "DESEJA CONSULTAR OUTRA ATUALIZACAO? (S/N)"
AT 2001
ACCEPT RESP AT 2044 WITH UPPER
END-PERFORM
CLOSE ARQ-ATUALIZACAO
EXIT PROGRAM
.
priming-READ-input-file.
PERFORM READ-input-file
IF end-of-input-file
DISPLAY "END OF FILE" AT 2510
END-IF
.
READ-input-file.
READ ARQ-ATUALIZACAO
IF NOT INPUT-FILE-OK
DISPLAY "FILE NOT OK" AT 2310
DISPLAY ST-ATUALIZACAO AT 2440
STOP " "
END-IF
.
process-input.
IF COD-RASTREIO = PROCURA
DISPLAY ID-ATUALIZACAO AT 2410
STOP " "
END-IF
.我在文件“atualizacao.dat”中拥有的示例数据是:
ID-ATUALIZACAO: 0000000001
鳕鱼-RASTREIO: qweqweqweqweqwee
泰图洛:测试
DESCRICAO:描述
ID-ATUALIZACAO: 0000000002
鳕鱼-RASTREIO: qweqweqweqweqwee
TITULO: test2
DESCRICAO: description2
发布于 2015-05-25 23:34:55
因为您的选择中有ACCESS RANDOM,所以READ file-name的默认操作(没有NEXT或KEY)是按键读取。
将其更改为ACCESS SEQUENTIAL
无论如何,将其更改为READ file-name NEXT,这是一个显式的顺序读取。
在读取时,我总是使用显式的NEXT或KEY,这样就不会依赖于默认行为,默认行为取决于文件的类型(和打开的类型)。
当我不小心地模仿别人的例子时,我忘了说清楚,很抱歉我错过了,因为你没有下一个例子。
因为您没有使用打开的I(您没有按键读取或启动,所以您不需要随机或动态的访问),所以只需使用OPEN ... INPUT。
您没有提到用户输入的需求状态。用户输入可能没有必要在循环中。
打开后不检查“文件状态”字段。你会发现你在那里有问题。在同一个程序中多次打开同一个文件是错误的做法,即使您多次关闭该文件(您没有这样做,因此可能会出现问题)。
好的,先读一下。好的,首先回到选择的文件状态。
在文件上使用文件状态将获得一个两个字节的字段,该字段将告诉您上一次IO操作发生了什么。如果该字段包含0,那么一切都很好。
我建议对您可能使用的所有文件使用文件状态,并在文件上的每个IO之后检查文件状态字段(每个文件保持它们唯一)。
使用文件的文件状态告诉COBOL运行时“我将处理出现的任何问题,您可以通过在这个字段中放置代码来告诉我什么时候出现了问题”。
如果您使用文件状态而不检查文件状态字段,IO错误就会悄悄消失。
现在再读一遍。
这将读取下一个可用的记录。
READ file-name如果遇到文件结束,文件状态字段将被设置为"10“。
您可以为文件状态字段定义一个88级别的条件名称:
01 input-file-status PIC XX.
88 end-of-input-file VALUE "10".您的循环可以是:
PERFORM
UNTIL end-of-input-file
READ input-file
END-PERFORM仅仅读取一个文件没有多大用处,您也需要处理这些数据。使代码更加复杂的一种方法是在读取和执行后测试输入文件的结束(如果不是):
PERFORM
UNTIL end-of-input-file
READ input-file
IF NOT end-of-input-file
PERFORM process-input
END-IF
END-PERFORM将其与“启动读取”进行比较,这意味着您在开始循环之前读取了第一个记录(如果存在的话):
READ input-file
PERFORM
UNTIL end-of-input-file
PERFORM process-input
READ input-file
END-PERFORM每次在执行过程中,都有一条可用于处理的记录,或者在上一次执行结束时已标识了文件结束。
把它与你所拥有的东西进行比较:
PERFORM
UNTIL ARE-THERE-MORE-RECORDS = 'NO '
READ ARQ-ATUALIZACAO
AT END
MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
NOT AT END
PERFORM 300-STORE-NAME
END-READ
END-PERFORM 我说在每个IO之后测试文件状态字段。这会让事情看起来很混乱,那么该如何避免呢?表演:
PERFORM READ-input-file
PERFORM
UNTIL end-of-input-file
PERFORM process-input
PERFORM READ-input-file
END-PERFORM然后,读取输入文件可以检查文件状态字段(具有88级),而不会使代码混乱。
进一步改进。您有两个“读”的执行,但它们并不相同,所以将它们命名不同:
PERFORM priming-READ-input-file
PERFORM
UNTIL end-of-input-file
PERFORM process-input
PERFORM READ-input-file
END-PERFORM然后:
priming-READ-input-file.
PERFORM READ-input-file
.现在代码和以前一样,但是讲了一个更好的故事。而且可以进一步改进,而不使下列情况复杂化:
priming-READ-input-file.
PERFORM READ-input-file
IF end-of-input-file
do something which says "hey, there should always be records,
a bad thing has happened" and then crash whilst DISPLAYing
necessary information
END-IF
.然后,您有一个通用的、简单的程序,它在循环中读取一个文件直到文件结束,您可以在任何需要的时候使用它作为基础。
您可以轻松地沿着相同的行扩展代码,以处理文件上的“文件头”,然后进行一些更改来处理“文件预告片”,确保每个文件中只有一个,头是第一,最后一个,头是正确的文件和正确的业务日期,并且预告片有正确的记录计数和散列总数。
所有这些都不会干扰程序的控制逻辑。
然后,您有第二个程序,您也可以使用作为一个基础。
对于您的任务,您首先需要与用户交互,存储用户数据,根据每条记录测试数据。这可能是一个用户输入,或几个,你没有说。
如果用户的输入取决于已经显示的结果,则只需要存储文件中的记录。可能是这样,你没说。
如果用户提供一段输入来匹配一个字段,那么在处理每个记录时,只需测试该值(已经获得)。
你原来的节目有问题:
文件状态用于选择,但不检查文件状态字段( STATUS )。
文件的第二个打开,这将失败(该文件已经打开)在300个存储名.
以300个商店名称结尾的文件。这会管用的。但是现在,当您进行下一次读取时,您的文件将关闭。这样读起来就不管用了。它将如何工作(确切地说,它将做什么)?嗯,我想,因为我不知道,因为我不这样编码,一个文件状态指定的关闭文件的读取和一个AT结束将导致AT端被处理。当然,FD下01级的内容将不明确。
每次向表中添加记录时,都试图搜索表。如果您确实需要将所有的记录存储在一个表中,那么只有在文件结束并且所有内容都在表中之后,才会执行SEARCHing。
一旦您有了一个工作程序,就会有另一个StackExchange站点,名为Code,您可以在那里询问如何使工作代码更好。
制作一个非常简单的程序,在循环中读取输入文件,直到文件结束。
在该程序开始时,获取用户输入。如果有多个用户输入,将其存储在一个出现的表中。
对于读取的每条记录,请对照用户数据(单个字段或表)进行检查,如果匹配,则生成输出。
请看这里的答案,Cobol Read statement format. Can it be redone a different way?,并按照链接进行操作。注意如何使用启动读取,以及如何使用文件状态字段实际检查错误,并确定文件的结束,而它是顺序读取。
https://stackoverflow.com/questions/30446035
复制相似问题