1

我想使用 FORTRAN 流式 I/O 来制作一个程序,告诉我一个文本文件有多少行。这个想法是做这样的事情:

OPEN(UNIT=10,ACCESS='STREAM',FILE='testfile.txt')

nLines=0
bContinue=.TRUE.

DO WHILE (bContinue)
   READ(UNIT=10) cCharacter
   IF (cCharacter.EQ.{EOL-char}) nLines=nLines+1
   IF (cCharacter.EQ.{EOF-char}) bContinue=.FALSE.
ENDDO

(我没有包括变量声明,但我想你知道它们是什么;唯一重要的说明是 cCharacter 的 LEN=1)

我的问题是我不知道如何检查我刚刚从文件中读取的字符是行尾还是文件尾(代码中的“ifs”)。当您以这种方式阅读和打印字符时,您最终会在原始文本中的相同位置获得换行符,所以我认为它确实会以某种方式将它们读取并识别为“字符”。也许将字符转换为整数并与适当的数字进行比较?还是有更直接的方法?

(我知道你可以使用寄存器读取(编辑:我的意思是记录读取)来做一个更容易读取行的程序并添加一个 IOstatus 来检查 eof,但是“行计数器”只是一个有用的例子,这个想法是学习如何通过文本文件以更可控的方式移动)

4

1 回答 1

2

检查特定字符作为行终止符使您的程序依赖于操作系统。最好使用该语言的功能,以便您的程序依赖于编译器和操作系统。既然行基本上是记录,为什么要用蒸汽 I/O 来做呢?这一要求似乎使一项容易的工作变成了一项艰巨的工作。如果可以使用常规 IO,这里有一个示例程序来计算文本文件中的行数。

编辑:代码片段已更改为程序以回答评论中的问题。使用“line”作为字符变量,当我使用 gfortran 和 ifort 测试程序时,当输入文件有空行或空行时,我看不到问题。

program test_lc

use, intrinsic :: iso_fortran_env

integer :: LineCount, Read_Code
character (len=200) :: line


open (unit=51, file="temp.txt", status="old", access='sequential', form='formatted', action='read' )

LineCount = 0

ReadLoop: do

   read (51, '(A)', iostat=Read_Code)  line

   if ( Read_Code /= 0 ) then
      if ( Read_Code == iostat_end ) then
         exit ReadLoop    ! end of file --> line count found
      else
         write ( *, '( / "read error: ", I0 )' )  Read_Code
         stop
      end if
   end if

   LineCount = LineCount + 1

   write (*, '( I0, ": ''", A, "''" )' )  LineCount, trim (line)
   if ( len_trim (line) == 0 ) write (*, '("The above is an empty or all blank line.")' )

end do ReadLoop

write (*, *) "found", LineCount, " lines"

end program test_lc

如果要对文件进行进一步处理,可以倒带。

附言

我使用 Fortran Stream IO 的主要原因是读取其他语言生成的文件,例如 C

提供了可移植的方法来编写换行符;我不知道有一种可移植的方法来测试这种情况。

于 2011-07-16T00:52:28.347 回答