首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Fortran ifstream等效

Fortran ifstream等效
EN

Stack Overflow用户
提问于 2015-09-28 18:26:06
回答 2查看 467关注 0票数 1

在C++中,可以使用std::ifstream从文件或字符串中读取。我想在现代FORTRAN中做同样的(或类似的)。

具体来说,我有一个现有的FORTRAN程序,它接受一个文件作为输入,并对它执行逐行读取操作。我是否可以很容易地将其转换为使用相同的逻辑在运行时解析文件或字符串?例如,如果使用read语句,它们应该处理文件或字符串。

更新

下面是一个简单的C++片段,展示了我想要做的事情。注意,我调用1 Parse()函数从文件或字符串导入:

代码语言:javascript
复制
void ImportFile( const std::string &file_name ) {
    std::istream is( file_name.c_str() );
    Parse( &is );
}

void ImportString( const std::string &str ) {
    std::stringbuf sbuf( str );
    std::istream is( &sbuf );
    Parse( &is );
}

void Parse( istream *is ) {
    std::string line;
    while( *is ) {
        getline( *is, line );

        // Process line ...
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-28 21:15:07

这是可能的,但取决于您的情况,这可能不是一个容易的转换,并且有一些限制和要求可能使它不合适。

用户定义的派生类型输入/输出是在Fortran 2003中引入的(因此您需要Fortran 2003编译器),它为文件读取(和写入)操作提供了一个接口,而不管原始文件是内部的还是外部的(即字符变量还是磁盘上的某些内容)。客户端代码简单调用READ语句的相关单位或字符变量,源代码路径从那里是常见的。

但是,这种方法要求将数据读入派生类型的对象(该对象可能具有明确为此目的而写的类型),并且对象的所有输入都在一条记录中(即数组元素(如果从字符变量读取),行(如果从文件读取)。

例如

代码语言:javascript
复制
MODULE m
  IMPLICIT NONE
  PRIVATE
  TYPE, PUBLIC :: t
    INTEGER :: a
    REAL :: b
    CHARACTER(:), ALLOCATABLE :: c
  CONTAINS
    PROCEDURE :: read_formatted
    GENERIC :: READ(FORMATTED) => read_formatted
  END TYPE t
CONTAINS
  ! For the sake of example, the form of our input is rather fixed.
  ! - a single character integer, followed by a blank.
  ! - a three character real, followed by a blank.
  ! - a one-or-more character character, followed by a blank or EOR.
  !
  ! i.e. "(I1,1X,F3.0,1X,A,:,1X,...)"

  SUBROUTINE read_formatted(dtv, unit, iotype, v_list, iostat, iomsg)
    CLASS(t), INTENT(INOUT) :: dtv
    INTEGER, INTENT(IN) :: unit
    CHARACTER(*), INTENT(IN) :: iotype
    INTEGER, INTENT(IN) :: v_list(:)
    INTEGER, INTENT(OUT) :: iostat
    CHARACTER(*), INTENT(INOUT) :: iomsg

    CHARACTER :: ch
    CHARACTER(LEN(iomsg)) :: local_iomsg

    READ (unit, "(I1,1X)", IOSTAT=iostat, IOMSG=iomsg)  dtv%a
    IF (iostat /= 0) RETURN

    READ (unit, "(F3.0,1X)", IOSTAT=iostat, IOMSG=iomsg)  dtv%b
    IF (iostat /= 0) RETURN

    dtv%c = ''
    DO
      READ (unit, "(A)", IOSTAT=iostat, IOMSG=local_iomsg) ch
      IF (iostat < 0) EXIT
      IF (iostat /= 0) THEN
        iomsg = local_iomsg
        RETURN
      END IF
      IF (ch == '') EXIT
      dtv%c = dtv%c // ch
    END DO
    iostat = 0
  END SUBROUTINE read_formatted
END MODULE m

PROGRAM p
  USE m
  IMPLICIT NONE
  TYPE(T) :: x

  CHARACTER(*), PARAMETER :: input_string  &
      = '1 2.0 three'

  INTEGER :: unit
  CHARACTER(:), ALLOCATABLE :: string

  string = input_string

  ! Read from a string.
  READ (string, "(DT)") x
  PRINT *, x%a, x%b, x%c

  ! Prepare an example of an external file to read from.
  OPEN ( NEWUNIT=unit,  &
      STATUS='SCRATCH',  &
      ACTION='READWRITE' )
  WRITE (unit, "(A)") input_string
  REWIND unit

  ! Read from an external unit.
  READ (unit, "(DT)") x
  PRINT *, x%a, x%b, x%c

  CLOSE(unit)
END PROGRAM P
票数 2
EN

Stack Overflow用户

发布于 2015-09-28 18:44:57

是的,您可以这样做,并且不需要对代码进行太多更改,因为read可以从文件或字符变量中读取。

考虑一下示例代码:

代码语言:javascript
复制
program test
  implicit none
  integer :: fin, varC, varC2
  real :: varA, varA2
  character(len=4) :: varB, varB2
  character(len=13) :: string_input = '1234.5 TEST 2'

  open(newunit=fin, file='filein.dat', form='formatted', access='stream', status='old')
  read(fin,*) varA, varB, varC
  print *, varA, varB, varC
  close(fin)

  read(string_input,*) varA2, varB2, varC2
  print *, varA2, varB2, varC2
end program test

和输入文件filein.dat

代码语言:javascript
复制
1234.5 TEST 2

执行此程序时,它会打印:

代码语言:javascript
复制
1234.50000     TEST           2
1234.50000     TEST           2

您可以看到,无论数据是在字符变量中还是通过文件IO单元访问,读取的内容基本上是相同的。对于文件大小写,提供单位编号,而字符串则提供包含数据的字符变量。

Fortran标准将字符变量上的IO称为“内部文件”。如果您的IO是面向记录的,您可以为每个记录提供一个字符标量,或者为每个数组元素提供一个带有一个记录的字符数组。内部文件的一个限制是不能在opencloseinquire语句中使用它们。这意味着不能将字符串与数字单位号相关联。字符变量本身必须在read语句中使用,而不是单元号。适应这一点可能是修改程序以从字符串读取而不是文件的最大障碍(除了将数据放入字符变量之外)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32829479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档