如何读取包含已知行数的数据文件,但每行中的条目数未知,例如如果我的数据文件包含某些内容,如
1 3 4 5 6 -7 8 -9
1 3 5 6
4 5 6 7 8 3 5 6 7 8 4 5 7 8
即。三行,但每行的数据是未知的。有一次我需要一行数据。
答案 0 :(得分:8)
一种方法:使用至少与最长预期行一样长的字符串将行读入字符串。然后你去解析字符串。例如,如果数字总是按空格分割,则使用它来计算子串边界。然后,您可以使用“内部读取”从每个子字符串中读取以获取数值。内部读取使用字符串而不是单元号并从字符串中获取数据 - 至少您不必重新创建字符到数值的转换,read语句将为您执行此操作。 Fortran提供的内部函数将使解析更容易。
答案 1 :(得分:2)
假设你可以用零填充数组(特别是指后面的重复问题here),这是我的想法:
逐行读取数据到一个字符串,然后附加一些零,最后从这个数组中读取每一行数据。这是一个例子:
program unknown_numbers
implicit none
integer, parameter :: nrow=3, ncol=14
integer :: data(ncol, nrow)
character(len=2*ncol) :: zeros ! will contain lots of zeros
character(len=10*ncol) :: line ! temporary storage for each line of the file
integer :: i, u
! Write " 0 0 0 0 0 0 0 0" into the string "zeros"
write(zeros, '(*(I2))') [(0, i=1, ncol)]
open(newunit=u, file='data.txt', status='old', action='read')
do i = 1, nrow, 1
! Read the next line into a temporary string array
read(u, '(A)') line
! Append a number of zeros to the temporary string
line = trim(line) // zeros
! Read the row of data from the string.
read(line, *) data(:, i)
end do
close(u)
! For testing purposes, print the data.
print '(14(X, I3))', data
end program unknown_numbers
答案 2 :(得分:1)
integer,parameter :: reclen=99999 ! maximum record length
integer,parameter :: undef=-9999 ! undefined value
integer :: actual_reclen ! actual record length
integer,dimension(reclen) :: dummy=undef ! dummy array used for reading
integer,dimension(:),allocatable :: a ! final array
open(unit=10,file='sample.txt',form='formatted',access='sequential')
read(unit=10,fmt=*,end=101)(dummy(i),i=1,reclen)
101 close(unit=10)
actual_reclen=COUNT(dummy/=undef)
allocate(a(actual_reclen))
a=dummy(1:actual_reclen)
end
答案 3 :(得分:1)
基于M.S. B.指出的实现。很晚了,但我想这可能对某人有用。
具有您希望已准备好阅读的类型的数组:
double precision, dimension(MAX_NUM_OF_COLS) :: test_array
从文件中读取一行:
READ(reading_unit,'(A)',iostat=io) line
循环并尝试从该行读取最大数量的数字:
do i=1,MAX_NUM_OF_COLS
READ(line, *, iostat=io) test_array(1:i)
if(io==0) exit
enddo
write(*,*) 'number of columns = ', (i-1)
如果需要,可以在文件的所有行上循环,并保留最大或最小列数。
最小示例:
integer, parameter :: MAX_NUM_OF_COLS=30
integer, parameter :: MAX_LINE_LENGTH=1000
character(len=MAX_LINE_LENGTH) line
integer i, io, reading_unit
double precision, dimension(MAX_NUM_OF_COLS) :: test_array
reading_unit=100
OPEN(reading_unit, file='the_file')
! Get first line of file.
DO
READ(reading_unit,'(A)',iostat=io) line
IF (io/=0) then
write(*,*) "Error reading file."
stop
endif
exit ! Eventually, do not exit and put the DO loop below here.
ENDDO
CLOSE(reading_unit)
do i=1,MAX_NUM_OF_COLS
READ(line,*,iostat=io) test_array(1:i)
if(io==-1) exit
enddo
write(*,*) 'number of columns = ', (i-1)
答案 4 :(得分:-3)
这是一个可以计算一行(或列数)但是一行的数字的程序。如果你有很多行,你应该稍微改一下。
program test12
implicit none
integer n,m,i
integer,allocatable::x(:)
open(10,file='C:\Users\user\Desktop\file.txt')
allocate(x(n))
20 n=n+1
deallocate(x)
allocate(x(n))
read(10,*,iostat=m)(x(i),i=1,n)
if (m==-1)then
goto 30
else
rewind 10
goto 20
end if
30 print*,n-1
end