在Fortran中使用命令行参数从数据文件中读取特定列
我有一个文本文件,看起来像这样:在Fortran中使用命令行参数从数据文件中读取特定列,fortran,fortran90,fortran95,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 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
)读取该文件的第三列。因此,如果用户只想从数据文件中读取特定列,他/她应该能够将其作为参数传递给运行可执行文件的命令。到目前为止,我只是在一个大的多维数组中读取整个数据,然后丢弃不需要的列。但是,由于文件太大,这会消耗大量内存。提前谢谢 一种可能的解决方案是逐行读取数据文件,并将所需的列存储在分配的数组中。无论如何,如果源数据太大,最好将临时值存储在动态分配的变量中,并在不再需要时立即返回内存(释放变量)
下面的示例显示了如何实现这一点。它读取源文件并将指定列打印到控制台
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
一种可能的解决方案是逐行读取数据文件,并将所需的列存储在分配的数组中。无论如何,如果源数据太大,最好将临时值存储在动态分配的变量中,并在不再需要时立即返回内存(释放变量) 下面的示例显示了如何实现这一点。它读取源文件并将指定列打印到控制台
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
主要的一点是,用户应该能够使用
getarg
之类的工具将要读取的列的编号传递给运行时。我在你的回答中看不到这点。@SnehalShekatkar这是一个小细节,你可以很容易地附加到你自己身上。这不是为您提供完全工作的软件的服务。如果你在自己的问题下否决了这样一个答案,那就是忘恩负义。谢谢@VladimirF!在这个答案中,我只想说明如何读取和处理大型数组。顺便说一下,我添加了一个块,它只需要并读取一个命令行参数。[@syscreatread(buffer,*)column
可能比read(buffer,“(I)”column
更好,因为gfortran抱怨“需要非负宽度…”@SnehalShekatkar我完全不同意。现在,它正是您所要求的,甚至在您真正需要它之前。主要的一点是,用户应该能够使用getarg
之类的工具将要读取的列数传递给运行时。我在你的回答中看不到这点。@SnehalShekatkar这是一个小细节,你可以很容易地附加到你自己身上。这不是为您提供完全工作的软件的服务。如果你在自己的问题下否决了这样一个答案,那就是忘恩负义。谢谢@VladimirF!在这个答案中,我只想说明如何读取和处理大型数组。顺便说一下,我添加了一个块,它只需要并读取一个命令行参数。[@syscreatread(buffer,*)column
可能比read(buffer,“(I)”column
更好,因为gfortran抱怨“需要非负宽度…”@SnehalShekatkar我完全不同意。现在它正是您所要求的,甚至在它成为您真正需要的所有内容之前。您是只想将该列写入一个文件,还是想将其存储在一个数组中,或者打算对其执行什么操作?您是只想将该列写入一个文件,还是想将其存储在一个数组中,或者打算对其执行什么操作?