我是从顺序行文件中读取的。逐行,到EOF,类似的东西
read bank-file at end
move 'Y' to end-of-bank
行的长度可变,从40到80个字符。我需要知道,每行有多少个字符。但是行可以以一些空格结束,我也需要数。所以我不能在程序中从变量中获取字符串的长度。 READ语句是否有返回值,它返回readed行中的字符数(直到达到CRLF)?
答案 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。