我有一个包含逗号分隔数字的文本文件,如下所示:
757.76019287, 759.72045898, 760.97259521, 763.45477295, 765.99475098, 770.2713623
不知道此文件中有多少这些数字;它有所不同,但仅限于几百个数字。
目标是:
打开此文件(例如customwav.txt
),找出此文件中存在多少个数字->将它们放入整数n
中。
将这些数字的内存分配到数组中->我已经有子例程可以为我执行此操作。
将数字行读取到此分配的数组中。
在Fortran中执行1和3的最佳方法是什么?
答案 0 :(得分:2)
假设您的文件只有一行,看来:
如果您知道数字的格式,则可以执行非高级I / O;例如,如果所有数字都是浮点数,它们使用12个空格,其中8个是小数位,并且它们之间用逗号分隔,后跟一个空格,最后一个数字后面没有逗号和空格。
integer, parameter :: DP = selected_real_kind(15,300)
real(kind=DP) :: x
real(kind=DP), allocatable :: xall(:)
integer :: u
integer :: n
character(len=2) :: c
open(newunit=u, file='customwav.txt',status='old',action='read')
n = 0
do
read(u, '(f12.8)', advance='no') x
n = n + 1
read(u, '(2a)', advance='no', eor=100) c
if (c .ne. ', ') STOP 'unknown format'
end do
100 write(*,*) n
allocate(xall(n))
rewind(u)
read(u, *) xall
close(u)
write(*,*) xall
如果您不知道格式或格式以非常规方式更改,则一种懒惰(效率低下)的方法是尝试一次读取整个数组。以下愚蠢的代码尝试通过将大小一一增加来尝试此操作,但是您可以进行二等分。
integer, parameter :: DP = selected_real_kind(15,300)
integer, parameter :: MaxN = 1000
real(kind=DP), dimension(MaxN) :: x
integer :: u
integer :: n
integer :: error
open(newunit=u, file='customwav.txt',status='old',action='read')
error = 0
n = 0
do while (error.eq.0)
read(u, *, iostat=error) x(1:n+1)
if (error .eq. 0) then
n = n + 1
rewind(u)
end if
end do
write(*,*) n
rewind(u)
read(u, *) x(1:n)
close(u)
write(*,*) x(1:n)
如果允许使用非Fortran工具,则可以使用以下shell命令计算(单行)文件中的逗号数
$ grep -o ',' customwav.txt | wc -l
因此,浮点数是该数字可能加一(取决于格式)。对于多行文件,您可以使用
获取每行逗号计数列表$ f=customwav.txt
$ for lin in $(seq $(cat $f | wc -l))
> do
> sed -n ${lin}'p' $f | grep -o ',' | wc -l
> done
答案 1 :(得分:1)
我处理未知文件的方法是先使用流I / O打开它,一次读取1个字符,然后计算文件中所有字符的出现:count_characters(0:255)。
这可以告诉您很多期望,例如:
LF indicates number of lines in file
CR indicates DOS file rather than unix file format
. can indicate real numbers
, can indicate csv file format
; / : can indicate other delimiters
presence of non-numeric characters indicates non-numeric information
E or e can indicate scientific format
/ or : can indicate date/time info
The count_<lf> + count_, is an estimate of numbers in the file.
此方法的优点是它可以识别可能要恢复的异常数据。最好将它作为独立的实用程序,因为解释可能很难编写。
答案 2 :(得分:1)
OP告诉我们该文件包含数百个实数,并用逗号整齐地分隔。这是将它们读入适当大小的数组的一种简单方法。这与文件中的行数无关。
首先,声明一个可分配的数组,以及一个用于处理文件结尾的整数,这将在以后出现
real, dimension(:), allocatable :: numbers
integer :: ios
...分配数组,但有一些开销。是的,我只是要一口气读取文件中的许多数字,所以我不会试图找出有多少数字。
allocate(numbers(1000))
...将每个值设置为一个保护值,其实用性稍后会变得很明显;这确实假定该文件将不包含所选的保护值
numbers = -huge(1.0)
...读取数字;我假设文件已经在单元inunit
read(inunit,*,iostat=ios) numbers
...此时ios
的值非零,但是对于问题中概述的简单情况,无需进行任何处理,我们被告知只有几百个其中。最后
numbers = pack(numbers, numbers>-huge(1.0))
将numbers
重新分配给正确的大小。