可能有許多方法可以做到這一點,以下就是這樣一個例子。在這裏,split()對列表中的所有值進行列表定向輸入的多次嘗試,直到遇到非數字字符或行尾。
subroutine split(line, vals, n)
implicit none
character(*), intent(in) :: line
real*8 :: vals(*), buf(10000)
integer :: n
n = 1
do
read(line, *, end=100, err=100) buf(1 : n) !! (See Appendix for why buf is used here)
val(1:n) = buf(1:n)
n = n + 1
enddo
100 continue
n = n - 1
end
program main
implicit none
character(200) :: line
real*8 :: vals(10000)
integer :: n
open(10, file="test.dat", status="old")
do
read(10, "(a)", end=500) line
call split(line, vals, n)
if (n == 0) then
print *, "comment line"
else
print *, nint(vals(1 : n))
endif
enddo
500 continue
close(10)
end
如果TEST.DAT包含在問題的整個線路,加上下面幾行
# additional data
1,2,3 , 4 , 5 # comma-separated integers
1.23e2 -4.56e2 , 777 # integer/floating-point mixed case
它給
comment line
5 7 8 9 10 13
93 102 92
105 107 110 145 147 112
97 98
12 54 55
15 17 21 23 45
43 47 48 51 62
comment line
1 2 3 4 5
123 -456 777
因此可以通過複製保存結果的每一行vals(1:n)中的值轉換爲所需的數組。
[附錄(感謝@francescalus)] 在上面的代碼中,數據被讀入一次buf(1:n),然後複製到val(1:n)。有人可能會認爲,這將是更爲直接的數據讀入VAL(1:N),使得
read(line, *, end=100, err=100) val(1 : n)
但是,不建議使用這種直接的方法,因爲VAL(1:N)是不確定的,當讀語句觸發「結束」或「錯誤」條件。雖然ifort和gfortran似乎仍然保留val(1:n)中的數據,即使滿足該條件(因此即使採用直接方法也能工作),但其他編譯器無法保證相同的行爲。相比之下,緩衝方法通過將數據先前保存到val(1:n)來避免此風險,以便未使用未定義的數據。這就是爲什麼上述代碼使用緩衝方法的原因,儘管它只有一個陳述更長。