我在阅读文件和在另一个文件中打印时遇到了一些问题。 问题是,如果我使用格式化文件,在第二行上有一些,格式不好,因为某些值有一个减号。 因此,根据线路,格式正在发生变化。这两行只是一个例子。但是日期和时间总是保持不变。
我的档案是这样的:
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
答案 0 :(得分:1)
正如您已经注意到,在读取语句中精确指定输入格式会使它们变得相当脆弱。 Fortran的*
列表导向读取是理想的,让编译器和运行时处理真实值格式的可变性,但那些讨厌的日期和时间会破坏它。
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