在给定的文件记录中,我需要先读取前两个整数元素,然后读取其余部分(大量真实元素),因为赋值取决于前两个。假设格式为前两个整数元素没有很好地定义。
解决问题的最佳方法可能是:
read(unitfile, "(I0,I0)", advance='no') ii, jj
read(unitfile,*) aa(ii,jj,:)
但在我看来,gfortran中不允许使用“(I0)”规范。
基本上,在unitfile中读取的文件可能类似于:
0 0 <floats>
0 10 <floats>
10 0 <floats>
100 0 <floats>
100 100 <floats>
很难用任何类似Fortran的固定字段格式规范来阅读。
有没有其他方法可以解决这个问题,显然是微不足道的问题?
答案 0 :(得分:3)
这会使用字符串操作来获取单个组件,由空格' '
和/或制表符(char(9)
)分隔:
program test
implicit none
character(len=256) :: string, substring
integer :: ii, jj, unitfile, stat, posBT(2), pos
real, allocatable :: a(:)
open(file='in.txt', newunit=unitfile, status='old' )
read(unitfile,'(a)') string
! Crop whitespaces
string = adjustl(trim(string))
! Get first part:
posBT(1) = index(string,' ') ! Blank
posBT(2) = index(string,char(9)) ! Tab
pos = minval( posBT, posBT > 0 )
substring = string(1:pos)
string = adjustl(string(pos+1:))
read(substring,*) ii
! Get second part:
posBT(1) = index(string,' ') ! Blank
posBT(2) = index(string,char(9)) ! Tab
pos = minval( posBT, posBT > 0 )
substring = string(1:pos)
string = adjustl(string(pos+1:))
read(substring,*) jj
! Do stuff
allocate( a(ii+jj), stat=stat )
if (stat/=0) stop 'Cannot allocate memory'
read(string,*) a
print *,a
! Clean-up
close(unitfile)
deallocate(a)
end program
对于文件in.txt
,例如:
1 2 3.0 4.0 5.0
这导致
./a.out
3.00000000 4.00000000 5.00000000
注意:这只是一个快速而简单的示例,可根据您的需要进行调整。
答案 1 :(得分:3)
[这个答案已经过重大修改:原件不安全。感谢IanH指出这一点。]
当我能负担得起时,我通常会尽量避免执行非列表导向的格式化输入。已经有一个字符串解析的答案非常普遍,但我会提供一些简单设置的建议。
当您放心地信任输入时,例如当它只是格式化时有点棘手(或者您很乐意将它留给编译器的边界检查),您可以使用
来处理您的示例案例read(unitfile, *) ii, jj, aa(ii, jj, :)
或者,如果数组部分比前两列直接给出的更复杂,则可以通过表达式,甚至是函数
read(unitfile, *) ii, jj, aa(fi(ii,jj), fj(ii,jj), :fn(ii,jj))
使用pure integer function fi(ii,jj)
等。甚至有可能在这些函数中进行范围验证(例如,返回0大小的部分)。
在更一般的情况下,但保持列表导向,可以使用缓冲区作为实际变量
read(unitfile, *) ii, jj, buffer(:) ! Or ... buffer(:fn(ii,jj))
! Validate ii and jj before attempting to access aa with them
aa(.., .., :) = buffer
其中缓冲区的大小合适。
您首先考虑的方法表明您对线的结构有一些合理的了解,包括长度,但是当ii
和jj
或类型(和不允许多态性读取)不知道,那么事情确实变得棘手。此外,如果一个人对验证输入非常敏感,或者甚至提供有意义的详细用户错误反馈,那么这不是最佳的。
最后,iostat
有帮助。