Fortran阵列输入 [英] Fortran array input

查看:59
本文介绍了Fortran阵列输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经一年没有做任何Fortran编程了,现在看来我已经很生锈了.因此,我不会为您提供所有失败的尝试,但会谦虚地请您在以下方面为我提供帮助.我有以下输入"文件

I haven't done any Fortran programming for year and it seems I'm rather rusty now. So, I won't provide you with all my failed attempts but will humbly ask you to help me with the following. I've got the following "input" file

1 5 e 4  
A b & 1  
c Z ; b  
y } " N  
t r ' +  

它可以具有更多的列和/或行.现在,我想将每个ASCII字符分配给数组x(i,j),以便在进行ICHAR转换后可以进一步处理它们.在此示例中,i = 1,4,j = 1,5,但是根据输入文件的不同,它可以是任何No.最简单的例子

It can have more columns and/or rows. I would now like to assign each of these ASCII characters to arrays x(i,j) so that I can process them further after ICHAR conversions. In this example i=1,4, j=1,5, but it can be any No depending on the input file. The simplest example

PROGRAM Example
integer :: i, j
CHARACTER, ALLOCATABLE, DIMENSION(:,:) :: A
READ *, A
ALLOCATE (A(i,j))
PRINT *, A
END PROGRAM Example

编译(Example.f95),但是

compiles (Example.f95) but

cat input | ./Example.f95

不提供任何输出.我将不胜感激关于如何将上述字符串作为数组的x(i,j)项导入程序的建议.

does not give any output. I would greatly appreciate an advice on how to import the afore-mentioned strings into the program as x(i,j) terms of an array.

推荐答案

您需要阅读第一行并确定该行中的字符.然后读取整个文件以确定行数.分配2D数组以容纳字符.然后读取文件并将每一行解析为2D数组.有更优雅的方式可以做到这一点,但是在这里

You need to read the first line and determine how characters there in the line. Then read the entire file to determine the number of lines. Allocate the 2D array to hold characters. Then read the file and parse each line into the 2D array. There are more elegant ways of doing this, but here you go

  program foo

  implicit none

  character(len=:), allocatable :: s
  character, allocatable :: a(:,:)
  integer fd, i, j, n, nr, nc
  !
  ! Open file for reading
  !
  open(newunit=fd, file='tmp.dat', status='old', err=9)
  !
  ! Determine number of characters in a row.  Assumes all rows
  ! are of the same length.
  !
  n = 128
1 if (allocated(s)) then
     deallocate(s)
     n = 2 * n
  end if
  allocate(character(len=n) :: s)
  read(fd,'(A)') s
  if (len_trim(s) == 128) goto 1
  s = adjustl(s)
  n = len_trim(s)
  deallocate(s)
  !
  ! Allocate a string of the correct length.
  ! 
  allocate(character(len=n) :: s)
  !
  ! Count the number of rows
  !
  rewind(fd)
  nr = 0
  do
     read(fd,*,end=2)
     nr = nr + 1
  end do
  !
  ! Read file and store individual characters in a(:,:)
  !
2 rewind(fd)
  nc = n / 2 + 1
  allocate(a(nr,nc))
  do i = 1, nr
     read(fd,'(A)') s
     do j = 1, nc
        a(i,j) = s(2*j-1:2*j-1)
     end do
  end do
  close(fd)
  write(s,'(I0)') nc
  s = '('  // trim(s) // '(A,1X))'
  do i = 1, nr
     write(*,s) a(i,:)
  end do
  stop
9 write(*,'(A)') 'Error: cannot open tmp.dat'
  end program foo

显然, GOTO 是Verbotem,在这里.这是一个优雅的解决方案.

Apparently, GOTO is verbotem, here. Here's an elegant solution.

  program foo

  implicit none

  character, allocatable :: s(:), a(:,:)
  integer fd, i, j, n, nr, nc

  ! Open file for reading
  open(newunit=fd, file='tmp.dat', status='old', access='stream', err=9)

  inquire(fd, size = n) ! Determine file size.
  allocate(s(n))        ! Allocate space
  read(fd) s            ! Read the entire file

  close(fd)

  nr = count(ichar(s) == 10)             ! Number of rows
  nc = (count(ichar(s) /= 32) - nr) / nr ! Number of columns 

  a = reshape(pack(s, ichar(s) /= 32 .and. ichar(s) /= 10), [nc,nr])
  a = transpose(a)

  do i = 1, nr
     do j = 1, nc
        write(*,'(A,1X)',advance='no') a(i,j)
     end do
     write(*,*)
  end do
  stop
9 write(*,'(A)') 'Error: cannot open tmp.dat'
  end program foo

这篇关于Fortran阵列输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆