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

COBOL reading sequential line file, count characters

在 COBOL 中,我正在从顺序行文件中读取。逐行,到 EOF,诸如此类

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

行的长度从 40 到 80 个字符不等。我需要知道每行有多少个字符。但是行可以以一些空格结尾,我也需要计算这些空格。所以我不能从程序中的变量中获取字符串的长度。 READ 语句中是否有任何 return 值,即读取行中的 returns 个字符数(直到达到 CRLF)?

编辑

如评论中所述,实际上 可以获取读取的字符数(字节),确实使用 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。


原版post

据我所知,执行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已经提到的,由于您没有提供额外的细节,我不得不做出一些假设。

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

以防万一你仍然不知道你有多少字节,试试这个:

unix/linux/pcs 上关于 cobol 的美妙之处在于,在大多数情况下,他们不检查文件结构,他们假设您足够聪明,可以告诉程序文件是什么,并且在文件复杂的情况下例如嵌入文件中的 MFCobol B-Tree 索引,文件头将完成其余工作。

我第一次接触 MFCobol 时,用户总是以损坏的文件告终,我们需要一种方法来快速了解问题出在哪里,所以我利用了这一事实,基本上解析了文件以寻找某些功能,例如x'0A' (UNIX) 或 CR/LF 会告诉我们有人 FTP 使用二进制传输将文件从 PC 传输到 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 看到一个值小于 space 的 ascii 值,它会在它前面的标志字节中放置一个二进制 0 值。这个标志字节在文件中取 space 时不是数据,它是一个文件结构标记,通常不会在您的输出计数中找到它自己,但是因为我们使文件二进制顺序,它不会在运行时从读取中删除,因此如果您看到 LOW-VALUE 或 x '00' 后跟一个值小于 x'20" 的字符,然后将输出字节数减少 1。