Fortran按列读取文本文件到一维数组的问题求助
Fortran按列读取文本数据到一维数组的问题
需求
读取一个24行15列的文本文件,将所有数据按先第1列、再第2列……直至最后一列的顺序存入一维数组z。
数据示例
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.16 0.16 0.17 0.18 0.19 0.19 0.19 0.19 0.18 0.18 0.18 0.18 0 0 0 0.31 0.33 0.35 0.37 0.37 0.39 0.39 0.37 0.37 0.37 0.37 0.37 0 0 0 0.47 0.49 0.52 0.55 0.56 0.58 0.58 0.56 0.55 0.55 0.55 0.55 0 0 0 0.48 0.51 0.55 0.59 0.6 0.61 0.61 0.59 0.59 0.59 0.59 0.59 0 0 0 0.48 0.53 0.57 0.62 0.63 0.64 0.63 0.62 0.62 0.62 0.62 0.62 10 34 0 0.49 0.55 0.6 0.66 0.68 0.69 0.68 0.67 0.67 0.67 0.67 0.67 0 0 0 0.49 0.57 0.63 0.7 0.72 0.73 0.73 0.72 0.72 0.72 0.72 0.72 0 0 0 0.49 0.59 0.65 0.75 0.77 0.78 0.77 0.77 0.77 0.77 0.77 0.77 0 0 0 0.49 0.61 0.68 0.79 0.81 0.83 0.82 0.81 0.82 0.82 0.82 0.82 0 0 0 0.49 0.63 0.7 0.83 0.86 0.87 0.87 0.86 0.87 0.87 0.87 0.87 0 0 0 0.49 0.65 0.73 0.87 0.9 0.92 0.92 0.91 0.92 0.92 0.92 0.92 0 0 0 0.49 0.67 0.76 0.91 0.95 0.97 0.96 0.95 0.97 0.97 0.97 0.97 0 0 0 0.49 0.69 0.78 0.95 0.99 1.01 1.01 1 1.02 1.02 1.02 1.02 0 0 0 0.49 0.71 0.81 0.99 1.04 1.06 1.06 1.05 1.07 1.07 1.07 1.07 0 0 0 0.49 0.73 0.83 1.04 1.08 1.11 1.1 1.09 1.11 1.11 1.11 1.11 0 0 0 0.49 0.75 0.86 1.08 1.13 1.15 1.15 1.14 1.16 1.16 1.16 1.16 0 0 0 0.49 0.77 0.88 1.12 1.18 1.2 1.2 1.19 1.21 1.21 1.21 1.21 0 0 0 0.49 0.77 0.88 1.12 1.18 1.2 1.2 1.19 1.21 1.21 1.21 1.21 0 0 0 0.49 0.77 0.88 1.12 1.18 1.2 1.2 1.19 1.21 1.21 1.21 1.21 24 48 72 0.49 0.77 0.88 1.12 1.18 1.2 1.2 1.19 1.21 1.21 1.21 1.21
现有代码
program readdata use, intrinsic :: iso_fortran_env implicit none integer :: i, j, k real :: z(360) integer :: iostat character(len=255) :: filename ! Set the text file name filename = 'D:/Shuvashish/Oyster Shaye/growth_z_for_sal_tem.txt' ! Open the text file open(15, file=filename, status='old',form='formatted') ! Read the data from the text file into the z array k = 1 do j = 1, 15 ! j is changing do i = 1, 24 ! when j=2 and k=25, iostat becomes -1 read(15,*,iostat=iostat) z(k) if (iostat < 0) exit ! exit loop if iostat is negative k = k + 1 end do end do ! Close the text file close(15) ! Print the values of z do k = 1, 360 print*, z(k) end do end program readdata
问题现象
读取完第1列的最后一个元素后,iostat变为-1,后续无法读取其他列。
问题原因
Fortran的顺序读取是行优先的,即按文件中数据的存储顺序依次读取(先读第一行所有元素,再读第二行,以此类推)。原代码试图通过嵌套循环按列读取,但实际读取的是文件的前24个数据(第一行全部15个+第二行前9个),当读到文件末尾时触发iostat=-1,后续循环无法继续。
解决方案
方法一:先读入二维数组,再转存为按列排列的一维数组(推荐)
逻辑清晰,仅读取一次文件,效率更高,适合新手:
program readdata use, intrinsic :: iso_fortran_env implicit none integer, parameter :: rows = 24, cols = 15 integer :: i, j, k real :: z(rows*cols) real :: temp(rows, cols) ! 二维数组临时存储所有数据 integer :: iostat character(len=255) :: filename ! 设置文件名 filename = 'D:/Shuvashish/Oyster Shaye/growth_z_for_sal_tem.txt' ! 打开文件并检查状态 open(unit=15, file=filename, status='old', form='formatted', iostat=iostat) if (iostat /= 0) then print *, '无法打开目标文件' stop end if ! 逐行读取数据到二维数组 do i = 1, rows read(15, *, iostat=iostat) temp(i, :) if (iostat /= 0) then print *, '读取第', i, '行时出错' stop end if end do ! 关闭文件 close(15) ! 将二维数组按列转存到一维数组z k = 1 do j = 1, cols do i = 1, rows z(k) = temp(i, j) k = k + 1 end do end do ! 打印结果 do k = 1, rows*cols print *, z(k) end do end program readdata
方法二:逐行读取并提取对应列元素
无需存储全部二维数据,但需要多次重置文件指针:
program readdata use, intrinsic :: iso_fortran_env implicit none integer, parameter :: rows = 24, cols = 15 integer :: i, j, k real :: z(rows*cols) real :: row_data(cols) ! 存储单行数据 integer :: iostat character(len=255) :: filename filename = 'D:/Shuvashish/Oyster Shaye/growth_z_for_sal_tem.txt' open(unit=15, file=filename, status='old', form='formatted', iostat=iostat) if (iostat /= 0) then print *, '无法打开目标文件' stop end if k = 1 do j = 1, cols rewind(15) ! 每次处理一列前,回到文件开头 do i = 1, rows read(15, *, iostat=iostat) row_data if (iostat /= 0) then print *, '读取第', i, '行时出错' stop end if z(k) = row_data(j) k = k + 1 end do end do close(15) do k = 1, rows*cols print *, z(k) end do end program readdata
内容的提问来源于stack exchange,提问作者ZVY545
相关产品推荐
相关产品推荐

