COBOL读取顺序行文件,计数字符

时间:2016-07-19 07:28:17

标签: cobol

COBOL中的

我是从顺序行文件中读取的。逐行,到EOF,类似的东西

           read bank-file  at end
            move 'Y'  to end-of-bank

行的长度可变,从40到80个字符。我需要知道,每行有多少个字符。但是行可以以一些空格结束,我也需要数。所以我不能在程序中从变量中获取字符串的长度。 READ语句是否有返回值,它返回readed行中的字符数(直到达到CRLF)?

2 个答案:

答案 0 :(得分:1)

修改

正如评论中所提到的,实际上 可以获取读取的字符数(字节数),实际上是RECORD VARYING DEPENDING ON子句:

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

    SELECT SOME-FILE
        ASSIGN TO "someFile.txt"
        ORGANIZATION IS LINE SEQUENTIAL.

DATA DIVISION.
FILE SECTION.

FD SOME-FILE
    RECORD VARYING 40 TO 80 DEPENDING ON SOME-LINE-LENGTH.

 01 SOME-LINE PIC X(80).

WORKING-STORAGE SECTION.

 77 SOME-LINE-LENGTH PIC 9(3).

现在,对于每次读取,记录长度都存储在SOME-LINE-LENGTH

READ SOME-FILE NEXT RECORD
DISPLAY SOME-LINE-LENGTH

我不确切知道哪些供应商支持它(可能几乎全部),但至少它与ACUCOBOL一起使用。

原帖

据我所知,执行READ语句时读取的字节数没有反馈。显然,字节会立即存储到FILE SECTION中的文件描述符所描述的记录中。

但是,您可以通过计算写入记录的字符数来计算读取的字节数 首先,将文件记录初始化为LOW-VALUES。然后阅读下一条记录;这会将读取的字节数移动到记录中。当读取的字节数小于记录大小时,记录末尾的字节保持不变。

MOVE LOW-VALUES TO YOUR-RECORD
READ YOUR-FILE NEXT RECORD
PERFORM VARYING SOME-COUNTER FROM 72 BY -1 UNTIL (SOME-COUNTER < 0)
    IF NOT (YOUR-RECORD(SOME-COUNTER : 1) = LOW-VALUES)
        EXIT PERFORM
    END-IF
END-PERFORM

SOME-COUNTER将包含行长度,假设文件中不存在NUL值。

我想当线条数量很大时会很费时,但至少你得到了你的线路长度。

正如Bill Woodger已经提到的,由于您没有提供其他详细信息,我不得不做出一些假设。

我自己在Windows 10上运行MicroFocus ACUCOBOL-GT。

答案 1 :(得分:0)

如果您仍然不知道有多少字节,请尝试以下操作:

关于unix / linux / pcs上cobol的奇妙之处在于,它们大多不检查文件结构,他们假设您足够聪明,可以告诉程序文件是什么,对于复杂的文件,例如一个嵌入文件中的MFCobol B树索引,其余文件头将完成。

我第一次接触MFCobol时,用户总是无休止地损坏文件,我们需要一种快速知道出什么问题的方法,因此我利用了这一事实,并基本上对文件进行了解析以寻找某些功能,例如x' 0A'(UNIX)或CR / LF,它将告诉我们有人使用二进制传输将文件从PC FTP传输到LINUX。它的功能完全符合我们的期望,最终我们将其发布为最终用户的实用程序。

基于此,您可以告诉文件它具有1个字节的记录,并以二进制顺序读取每个字节。这样一来,您便可以计算字节数。将文件定义更改为BINARY SEQUENTIAL,记录大小为pic x(01)。由于您声明记录终止符为CR / LF,因此需要2个字节的字段来进行模式识别,并减少分隔符的字节数。

SELECT SOME-FILE
    ASSIGN TO "someFile.txt"
    ORGANIZATION IS BINARY SEQUENTIAL.

 DATA DIVISION.
 FILE SECTION.

 FD SOME-FILE
    01 SOME-BYTE PIC X(01).

 WORKING-STORAGE SECTION.
 01 PATTERN-BUFFER.
    05  PB-01  PIC X(01).
    05  PB-02  PIC X(01).
 01  BYTE-COUNT      PIC 9(9) VALUE ZERO.
 01  END-OF-SOME-FILE   PIC X(01) VALUE IS "N"

PROCEDURE DIVISION.
MAIN.
  open SOME-FILE.
  READ SOME-FILE INTO SOME-BYTE
  AT END
     CLOSE SOME-FILE
     DISPLAY  "BYTE-COUNT: 0"
     STOP RUN
  NOT AT END
      MOVE 1 TO BYTE-COUNT
      PERFORM UNTIL END-OF-SOME-FILE="Y"
         READ SOME-FILE       **  (1 byte record)
           AT END MOVE "Y" TO END-OF-SOME-FILE
              DISPLAY BYTE-COUNT
              STOP RUN
           NOT AT END
              ADD 1 to BYTE-COUNT
              MOVE PB-02 to PB-01 
              MOVE SOME-BYTE TO PB-02
              IF PATTERN-BUFFER = x'0D0A'
                 SUBTRACT 2 FROM BYTE-COUNT
              ELSE
                 IF PB-01 = x'00" AND PB-02 < X'20'   <<=== SEE NOTE
                    SUBTRACT 1 FROM BYTE=COUNT
                 END-IF
              END-IF
         END-READ
     END-PERFORM
END-READ

MF COBOL可以对LINE SEQUENTIAL文件做两件事,这可能会干扰您的计数。

第一个方法是删除所有尾随空格...但是根据规范,您希望实际存储的字节数应该没问题。

第二个是标记在某些情况下可能会被误解的字符。对于看起来像二进制整数值的回车控制字符尤其如此。如果MF Cobol看到的值小于空格的ascii值,它将在其前面的标志字节中放置一个二进制0值。在文件中占用空间时,此标志字节不是数据,它是文件结构标记,通常不会在您的输出计数中找到自己,但是因为我们使文件成为二进制顺序文件,所以它在运行时不会从读取中删除,因此如果看到LOW-VALUE或x'00'后跟一个字符小于x'20“的值,则将输出字节数减少1。