我有这个数据集,我想用Fortran阅读它并应用一些操作。我已经提供了下面的数据集。这是对数据集的简短描述。数据集以时间戳开始,随后的行(约60或120)是此时记录的数据点,后面再跟着时间戳和数据,依此类推。每个文件有大约30个观测值,有15个不同的时间戳(即两个相邻的观测值具有相同的时间戳)。我现在想读取这个文件,并使用相同的时间戳执行诸如在数据点上添加或减少列的操作。
这里' 6:31:5',' 6:27:9'是数据后跟的时间戳。
请帮忙,因为我无法找到办法。 非常感谢你。
答案 0 :(得分:1)
你的问题留下了很多含糊之处。我理解它的方式是你想要读取一个文件,其中一行的内容可能是两个不同的东西之一:一个值或一个时间戳。
在你阅读它之前,你不知道它是哪一个。
我认为最好的方法是首先将该行读入字符串。
character(len=20) :: line
read(1001, '(A)') line
然后,根据该字符串中的第一个字符,您可以推断出它是哪一个。
if (line(1:1) == "'") then
! It's a time stamp
else
! It's a new value
end if
如果它是一个值,你可以直接从行变量中读出它:
read(line, *) val
阅读时间戳更复杂,因为我不太清楚冒号在里面的位置。如果小时数都是一位数,你就可以得到类似的东西:
read(line, '(X, I1, X, I2, X, I2)') hour, minute, second
但是因为有几个小时不能用一个数字写,所以我很怀疑。
所以我建议您创建一个使用INDEX
函数定位冒号的子例程,然后对该行进行切片以分别读取每个值。
hm = index(line, ':', back=.FALSE.) ! hour-minute separator
ms = index(line, ':', back=.TRUE.) ! minute-second separator
read(line(2:hm-1), *) hour
read(line(hm+1:ms-1), *) minute
read(line(ms+1:), *) second
全部放在一起:
program timestamp
implicit none
integer, parameter :: runit = 1001
integer :: io_err
character(len=20) :: line
real :: val
integer :: hour, minute, second
open(unit=runit, file='data.txt', action='READ', status='OLD', iostat=io_err)
if (io_err /= 0) then
write(*, *) "Unable to open file"
stop 1
end if
do
read(runit, '(A)', iostat=io_err) line
if (io_err == -1) then
write(*, *) "End of file"
exit
end if
if (line(1:1) == "'") then
call read_timestamp(line, hour, minute, second)
write(*, '(A, 2(I2.2, ":"), I2.2)') "New timestamp: ", hour, minute, second
else
read(line, *) val
write(*, *) "Data: ", val
end if
end do
close(runit)
contains
subroutine read_timestamp(line, hour, minute, second)
implicit none
character(len=*), intent(in) :: line
integer, intent(out) :: hour, minute, second
integer :: hm, ms ! Indices of separators
hm = index(line, ':', back=.FALSE.)
ms = index(line, ':', back=.TRUE.)
read(line(2:hm-1), *) hour
read(line(hm+1:ms-1), *) minute
read(line(ms+1:), *) second
return
end subroutine read_timestamp
end program timestamp