Fortran 使用非前进I/O从文件中读取和计数(双精度)实数:使用什么编辑描述符?
我试图从外部文件中将实数列表读入数组。我不知道一个文件中每个记录有多少记录字段(以空格分隔),因此我计划使用非前进I/O来首先计算记录字段的数量,然后分配一个足够大的实际数组,最后将文件读入同一数组 下面是一个示例输入文件(其中,每个记录字段的编辑描述符应为Fortran 使用非前进I/O从文件中读取和计数(双精度)实数:使用什么编辑描述符?,fortran,Fortran,我试图从外部文件中将实数列表读入数组。我不知道一个文件中每个记录有多少记录字段(以空格分隔),因此我计划使用非前进I/O来首先计算记录字段的数量,然后分配一个足够大的实际数组,最后将文件读入同一数组 下面是一个示例输入文件(其中,每个记录字段的编辑描述符应为f3.1,即一个3个字符宽的浮点,带一个小数点,并计算点;但如果我正确读取Metcalf等人的数据,则忽略小数点): 我的程序的MWE看起来像这样 program testread use iso_fortran_env i
f3.1
,即一个3个字符宽的浮点,带一个小数点,并计算点;但如果我正确读取Metcalf等人的数据,则忽略小数点):
我的程序的MWE看起来像这样
program testread
use iso_fortran_env
implicit none
character(len=255) :: filename
filename = 'read.dat'
print *, count_entries(filename)
contains
integer function count_entries(coefficient_file) result(n)
character(len=*), intent(in) :: coefficient_file
!real, dimension(:), allocatable :: coefficients
integer :: fileunit, stat
real :: temp
n=0
open(newunit=fileunit, file=coefficient_file, iostat=stat)
do
read(fileunit,'(f3.1)',advance='no',iostat=stat) temp
if (stat == iostat_end) then
exit
else
n = n + 1
end if
print *, stat, temp
end do
close(fileunit)
! What should happen in the future...
!allocate(coefficients(n))
!read(fileunit,*,iostat=stat) coefficients
end function count_entries
end program testread
如果将上面的示例输入保存为read.dat
,使用gfortran-o testread{.f90}
编译程序并执行它,您将得到以下结果:
0 1.00000000
0 2.00000000
0 0.300000012
0 0.00000000
0 4.00000000
0 5.00000000
-2 0.00000000
7
换句话说,它不计算5个条目,而是计算7个条目。这并不奇怪,因为出于某种原因,它看到了7个数字。但我想知道:为什么它会看到7个数字?如何将我的函数扩展到a)也能够读取较大的实数和b)读取非均匀宽度的实数?例如,我希望能够读取1.01 1.003 2.1
,等等。它看到六个数字(最后一个是记录结束条件),因为您的格式规范指定每次读取三个字符,但您的数据每四列间隔一次(三个用于数据,一个用于分隔空白)
如果输入的格式不固定(列数可能不同),则将整个记录(行)读入可分配的字符(:),然后手动切碎该字符串
(除非您知道您的输入将始终适合于指定小数位数的格式规范,否则切勿使用具有指定小数位数的格式规范进行输入。)您忘了考虑空格。只需使用'(f3.1,1x)
不幸的是,您显然调用了与Fortran标准中的含义不同的record。通常在文本文件中,一条记录是一行;我编辑了我的问题部分,其中我指的是空格分隔的字段,但写的是“记录”。在Freenode上的##fortran中,有人向我指出certik的fortran utils,其中包含的过程loadtxt
完全按照您的建议进行。因此我最终使用了:@mSSMloadtxt
的实际实现实际上非常不同,但这是一个很好的选择。@VladimirF我在考虑如何按照IanH的建议实现它。但是,正如他所说,在我的脑海中,“切碎绳子”也需要沿着绳子走,并决定下一个空间何时到来,对吗?还是有更优雅的方式?
0 1.00000000
0 2.00000000
0 0.300000012
0 0.00000000
0 4.00000000
0 5.00000000
-2 0.00000000
7