Fortran从.dat文件中读取:日期,时间,42 x real_values

时间:2015-10-30 14:33:26

标签: fortran gfortran

我在阅读文件和在另一个文件中打印时遇到了一些问题。 问题是,如果我使用格式化文件,在第二行上有一些,格式不好,因为某些值有一个减号。 因此,根据线路,格式正在发生变化。这两行只是一个例子。但是日期和时间总是保持不变。

我的档案是这样的:

22/03/2015 00:00:43 2.50E+4 1.66E+3 2.22E+3 2.70E+3 3.16E+3 3.83E+3 3.58E+3 3.69E+3 3.64E+3 2.45E+2 1.67E+2 3.64E+1 1.56E+1 7.47E+0 3.21E+0 2.09E+0 1.48E+0 1.39E+0 7.75E-1 7.20E-1 6.05E-1 6.45E-1 4.90E-1 3.65E-1 3.30E-1 1.46E-1 1.09E-1 6.10E-2 4.90E-2 4.10E-2 1.00E-2 9.00E-3 4.00E-3 1.00E-3 0.00E+0 0.00E+0 0.00E+0 0.00E+0 0.00E+0 0.00E+0 0.00E+0 0.00E+0
22/03/2015 16:14:35 1.26E+4 8.36E+2 1.12E+3 1.36E+3 1.59E+3 1.92E+3 1.80E+3 1.85E+3 1.83E+3 1.23E+2 8.36E+1 2.05E+1 9.87E+0 5.02E+0 2.84E+0 1.88E+0 1.49E+0 1.72E+0 1.06E+0 8.34E-1 8.22E-1 5.72E-1 4.61E-1 2.22E-1 2.78E-1 3.59E-1 2.40E-1 1.40E-1 8.90E-2 4.80E-2 4.60E-2 2.80E-2 1.60E-2 6.00E-3 5.00E-3 -1.00E-3    1.00E-3 3.00E-3 0.00E+0 0.00E+0 2.00E-3 1.00E-3

代码:

        PROGRAM LECT

        REAL tot_count(42)

        CHARACTER (10) :: stringdate, date
        CHARACTER (8) :: stringtime,time
        CHARACTER (2) :: day, hour
        CHARACTER (2) :: month,minutes, seconds
        CHARACTER (4) :: year

        OPEN(2,FILE='date.dat')
        OPEN(6,FILE='test.txt', STATUS='UNKNOWN')

 1      READ(2,11,advance='yes',end=9)
     & stringdate, stringtime, (tot_count(I),I=1,42)

        day=stringdate(1:2)
        month=stringdate(4:5)
        year=stringdate(7:10)
        date=day//'/'//month//'/'//year

        hour=stringtime(1:2)
        minutes=stringtime(4:5)
        seconds=stringtime(7:8)
        time=hour//':'//minutes//':'//seconds

         WRITE(6,*) date,' ', time, (tot_count(I),I=1,42)

        GOTO 1

   11 FORMAT(A10,1X,A8,1X,
     & F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,
     & F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,
     & F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,
     & F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,
     & F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,
     & F7.2,1X,F7.2,1X)
 9      CLOSE(2)
        CLOSE(6)

        END

2 个答案:

答案 0 :(得分:1)

正如您已经注意到,在读取语句中精确指定输入格式会使它们变得相当脆弱。 Fortran的*列表导向读取是理想的,让编译器和运行时处理真实值格式的可变性,但那些讨厌的日期和时间会破坏它。

嗯,这是个主意。假设您的行最多为256个字符

character(len=256) :: aline
...
read(2,*) aline
...
date = aline(1:10)
time = aline(12:19)
! decompose date and time into their elements if you want to
read(aline(20:256),*) tot_count

我没有对此进行过测试,因此几乎肯定会出现轻微的语法错误,但这种方法听起来还不够。

答案 1 :(得分:1)

我会使用列表导向输入而不是硬编码格式。首先,我会改变

11 FORMAT(A10,1X,A8,1X,
     & F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,
     & F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,
     & F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,
     & F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,
     & F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,F7.2,1X,
     & F7.2,1X,F7.2,1X)

11 format(A10,1X,A8,1X)

这种格式足以读取您的行标题以获取日期和时间。接下来,我会改变

 1      READ(2,11,advance='yes',end=9)
     & stringdate, stringtime, (tot_count(I),I=1,42)

进入

1  READ(2,11,advance='no',end=9) stringdate, stringtime
   read(2,*,end=9) (tot_count(I),I=1,42)

这将使用格式说明符读取前两个字段,而不是使行前进,然后使用列表定向输入读取接下来的42个值。进行这两项更改并使用输入数据文件会生成输出:

 22/03/2015 00:00:43   25000.0000       1660.00000       2220.00000       2700.00000       3160.00000       3830.00000       3580.00000       3690.00000       3640.00000       245.000000       167.000000       36.4000015       15.6000004       7.46999979       3.21000004       2.08999991       1.48000002       1.38999999      0.774999976      0.720000029      0.605000019      0.644999981      0.490000010      0.365000010      0.330000013      0.145999998      0.108999997       6.10000007E-02   4.89999987E-02   4.10000011E-02   9.99999978E-03   8.99999961E-03   4.00000019E-03   1.00000005E-03   0.00000000       0.00000000       0.00000000       0.00000000       0.00000000       0.00000000       0.00000000       0.00000000    
 22/03/2015 16:14:35   12600.0000       836.000000       1120.00000       1360.00000       1590.00000       1920.00000       1800.00000       1850.00000       1830.00000       123.000000       83.5999985       20.5000000       9.86999989       5.01999998       2.83999991       1.88000000       1.49000001       1.72000003       1.05999994      0.833999991      0.822000027      0.572000027      0.460999995      0.222000003      0.277999997      0.358999997      0.239999995      0.140000001       8.90000015E-02   4.80000004E-02   4.60000001E-02   2.80000009E-02   1.60000008E-02   6.00000005E-03   4.99999989E-03  -1.00000005E-03   1.00000005E-03   3.00000003E-03   0.00000000       0.00000000       2.00000009E-03   1.00000005E-03