Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Stream 如何使用Fortran中的流I/O检查EOF/EOL?_Stream_Io_Fortran_Eof_Eol - Fatal编程技术网

Stream 如何使用Fortran中的流I/O检查EOF/EOL?

Stream 如何使用Fortran中的流I/O检查EOF/EOL?,stream,io,fortran,eof,eol,Stream,Io,Fortran,Eof,Eol,我想使用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

我想使用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,但“行计数器”只是一个有用的例子,其思想是学习如何通过文本文件以更可控的方式移动)

检查作为行终止符的特定字符会使程序依赖于操作系统。最好使用该语言的功能,使您的程序依赖于编译器和操作系统。既然行基本上都是记录,为什么要使用steam 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


提供可移植的方法来写入新的线边界;我不知道有哪种便携式方法可以测试这种情况。

是的,我知道我作为示例使用的任务可以通过读取记录来完成。但是,关于您的代码,我想指出一点:我不知道这是因为编译器、计算机还是所有代码中都发生了这种情况,但是如果保存读入变量“line”,它将跳过空行。由于您没有对任何其他内容使用“行”,如果您只是“读取”而不将其保存在任何变量中,则可以修复此问题(这样所有行都将被计数)。然而,例如,没有办法知道使用寄存器的文本中的空行在哪里。我知道这听起来可能很愚蠢,但我想知道一种比记录读取更通用/精确的文本文件处理方法(我在主要问题中使用了“寄存器”,但我指的是记录)。例如,使用stream搜索单词比使用record要容易得多(不可能只复制文本的一部分,因为正如我所说的,如果读入变量,它将跳过eol)。你知道一种不可移动的检查EOL的方法吗?有多少是“不可携带的”?显然我更喜欢便携式的,但知道一种不完美的方式总比不知道要好。我怎么不明白为什么你们认为把测试读成行/记录不是万能的。你是否担心单词越界?否则,我不明白为什么使用流io搜索单词会容易得多。如果您将文件视为一组字符,很容易想象如何检查单词或单词的一部分(检查第一个字母,然后检查以下是否合适,等等);而且,你知道如何定位它;您可以简单地将第一个字母的位置作为字符返回。对于记录,我看不清楚如何查找单词或单词的一部分(例如,假设您正在查找“能量”,而文本总共只有“totalenergy”),如果您这样做,我看不到如何轻松找到它(为reg定义“位置”更为棘手).标准方法是猜测可能的最长行长度,并在该长度处声明变量。然后,当您将记录读入字符串时,如果记录较短,则变量将在右侧填充空格。这不是一个问题,因为您正在搜索非空单词,例如“energy”--将该单词作为子字符串扫描字符串。这可能是一个问题,因为您希望区分输入文件中的空行(即,行终止符前面没有任何内容)和在行终止符前面有一些空格/空格的行。