使用命令行参数从Fortran中的数据文件中读取特定列

时间:2016-07-12 05:37:44

标签: fortran fortran90 fortran95

我有一个看起来像这样的文本文件:

          0   0.258  -0.188  -0.446  -0.035   0.351  -0.317   1.361   1.066   1.198   1.115   1.208   0.804  -0.084  -0.643   0.201
          1   0.265  -0.193  -0.457  -0.036   0.361  -0.325   1.361   1.068   1.197   1.113   1.208   0.803  -0.082  -0.653   0.202
          2   0.264  -0.190  -0.453  -0.037   0.358  -0.322   1.363   1.070   1.200   1.115   1.212   0.806  -0.080  -0.658   0.201
          3   0.264  -0.182  -0.446  -0.041   0.354  -0.314   1.363   1.073   1.200   1.113   1.212   0.806  -0.082  -0.659   0.198
          4   0.257  -0.180  -0.436  -0.038   0.346  -0.308   1.359   1.067   1.198   1.111   1.208   0.802  -0.084  -0.655   0.194
          5   0.260  -0.176  -0.436  -0.042   0.348  -0.306   1.357   1.065   1.193   1.109   1.204   0.801  -0.083  -0.648   0.193

我想只读取一个特定的列,使用命令行参数(可能是getarg)来说明此文件中的第三列。因此,如果用户想要只读取数据文件中的特定列,他/她应该能够将其作为参数传递给运行可执行文件的命令。截至目前,我只是在一个大的多维数组中读取整个数据,然后丢弃不需要的列。但是,由于文件太大,这会占用大量内存。提前致谢。

1 个答案:

答案 0 :(得分:2)

可能的解决方案之一是逐行读取数据文件并在分配的数组中存储所需的列。无论如何,如果源数据太大,最好将临时值存储在动态分配的变量中,并在不再需要时立即返回内存(释放变量)。

以下示例显示了如何实现这一目标。它读取源文件并将指定的列打印到控制台。

program read_columns

    use, intrinsic :: iso_fortran_env, only: iostat_end
    implicit none

    ! array to store one source line
    real, dimension(16) :: array

    character(len=16) :: buffer

    integer unit
    integer status
    integer column

    ! suppose we have only one command line argument
    if (command_argument_count() >= 1) then
        call get_command_argument(1, buffer)
        write (*,*) buffer
        read (buffer, '(i)') column
    end if

    open(newunit = unit, file = 'big_table.txt', status = 'old', action = 'read')
    do
        read(unit, *, iostat = status) array
        if (status == iostat_end) then
            exit
        end if

        if (status > 0) then
            error stop 'Could not read a file.'
        end if

        ! fifth column to print
        write(*, '(f8.3)') array(column)
    end do

    close(unit)
end