我对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
复制相似问题