You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:12:01