Fortran Coder

标题: 关于批量处理文件后输出结果 [打印本页]

作者: wxy    时间: 2017-2-1 22:20
标题: 关于批量处理文件后输出结果
本帖最后由 wxy 于 2017-2-2 11:24 编辑

第27到第34行是用的群里的批量处理的代码,读入30个文件 运行后出现图片中的错误,并且result.txt文件中只有第1个文件的结果 要想输出全部30个结果应该怎么改
[Fortran] 纯文本查看 复制代码
module typedef
    type tdd
        integer :: stat=0
        real ::  tmax , tmin ,  total , average
    end type
end module

Integer Function DaysInYear( year , mon , day )
    Integer :: year , mon , day
    Integer :: DaysInMonth(12) = [31,28,31,30,31,30,31,31,30,31,30,31]
    If ( ( (MOD(year,4)==0).and.(MOD(year,100)/=0) ) .or. (mod(year,400)==0) )then
      DaysInMonth(2) = 29
    Else
      DaysInMonth(2) = 28
    End If
    DaysInYear = sum( DaysInMonth(:mon-1) ) + day
End Function DaysInYear

PROGRAM MAIN
  USE typedef
  implicit none
  real::rain
  type(tdd),allocatable::t(:)! 保存气温值
  type(tdd):: total !日均温累加
  integer i , m , dy , start , end , year , mon , day , DaysInYear , k
  character(len=20) :: line , filename='CN174654 (12)'
    open(8,file='result.txt')

   !批量处理
  do k=1,30
    !内部文件读写, 将 filename 第 8-11 字符换为相应年份
    write(filename(11:12),'(i2)') k
    open(7,file=filename)
    !获取行数
  I=0
  do
    READ(7,*,end=100) line
    i=i+1
  end do
  100 m = i - 1 !//你这个前面只多了一行
  rewind(7)
  allocate( t(m))
  read(7,*)

!初始日期转换为一年的第几天
    write(*,*)"year:"
    read(*,*)year
    write(*,*)"mon:"
    read(*,*)mon
    write(*,*)"day:"
    read(*,*)day

    print *,DaysInYear( year , mon , day )
    start=DaysInYear( year , mon , day )
!结束日期转化为一年的第几天
    write(*,*)"year:"
    read(*,*)year
    write(*,*)"mon:"
    read(*,*)mon
    write(*,*)"day:"
    read(*,*)day
    print *,DaysInYear( year , mon , day )
    end=DaysInYear( year , mon , day )

  do i=1,m
    read(7,*)dy , t(i)%tmax , t(i)%tmin , rain
    t(i)%average=(t(i)%tmax+t(i)%tmin)/2    !日均温
  end do
    total%average = 0
  do i=start,end
    total%average=total%average+t(i)%average    !日均温累加=积温
  enddo
  write(8,*) total%average    !
  close(8)
end do
end PROGRAM



QQ截图20170201220710.png (9.12 KB, 下载次数: 280)

QQ截图20170201220710.png

QQ截图20170201221715.png (21.58 KB, 下载次数: 281)

QQ截图20170201221715.png

作者: fcode    时间: 2017-2-2 12:46
你忘了 Close 7 和 deallocate(t)
作者: wxy    时间: 2017-2-2 13:08
本帖最后由 wxy 于 2017-2-2 13:32 编辑
fcode 发表于 2017-2-2 12:46
你忘了 Close 7 和 deallocate(t)

添加后可以运行了,但是输出结果还是只有一个,是不是位置放错了。
然后就是每个文件要输入两个年月日 ,运行之后发现,我要读入30个文件,就要重复输入60次,一不小心输错了就得重输,我想只输入一次就能实现对全部文件重复操作,是哪里出错了吗
[Fortran] 纯文本查看 复制代码
module typedef
    type tdd
        integer :: stat=0
        real ::  tmax , tmin ,  total , average
    end type
end module

Integer Function DaysInYear( year , mon , day )
    Integer :: year , mon , day
    Integer :: DaysInMonth(12) = [31,28,31,30,31,30,31,31,30,31,30,31]
    If ( ( (MOD(year,4)==0).and.(MOD(year,100)/=0) ) .or. (mod(year,400)==0) )then
      DaysInMonth(2) = 29
    Else
      DaysInMonth(2) = 28
    End If
    DaysInYear = sum( DaysInMonth(:mon-1) ) + day
End Function DaysInYear

PROGRAM MAIN
  USE typedef
  implicit none
  real::rain
  type(tdd),allocatable::t(:)! 保存气温值
  type(tdd):: total !日均温累加
  integer i , m , dy , start , end , year , mon , day , DaysInYear , k
  character(len=20) :: line , filename='CN174654 (12)'
    open(8,file='result.txt')

   !批量处理
  do k=1,30
    !内部文件读写, 将 filename 第 8-11 字符换为相应年份
    write(filename(11:12),'(i2)') k
    open(7,file=filename)
    !获取行数
  I=0
  do
    READ(7,*,end=100) line
    i=i+1
  end do
  100 m = i - 1 !//你这个前面只多了一行
  rewind(7)

  allocate( t(m))
  read(7,*)

  do i=1,m
    read(7,*)dy , t(i)%tmax , t(i)%tmin , rain !读入数据
    t(i)%average=(t(i)%tmax+t(i)%tmin)/2    !日均温
  end do
    total%average = 0

!初始日期转换为一年的第几天
    write(*,*)"year:"
    read(*,*)year
    write(*,*)"mon:"
    read(*,*)mon
    write(*,*)"day:"
    read(*,*)day

    print *,DaysInYear( year , mon , day )
    start=DaysInYear( year , mon , day )
!结束日期转化为一年的第几天
    write(*,*)"year:"
    read(*,*)year
    write(*,*)"mon:"
    read(*,*)mon
    write(*,*)"day:"
    read(*,*)day

    print *,DaysInYear( year , mon , day )
    end=DaysInYear( year , mon , day )


  do i=start,end
    total%average=total%average+t(i)%average    !日均温累加=积温
  enddo
  write(8,*) total%average    ! 结果写入另一个文件
  close(8)
  deallocate(t)
  Close(7)

  end do

end PROGRAM

作者: fcode    时间: 2017-2-2 16:07
    write(*,*)"year:"
    read(*,*)year
    write(*,*)"mon:"
    read(*,*)mon
    write(*,*)"day:"
    read(*,*)day

把这些放到循环外面就可以了。

close(8) 请放到循环外面。
作者: wxy    时间: 2017-2-2 16:25
fcode 发表于 2017-2-2 16:07
write(*,*)"year:"
    read(*,*)year
    write(*,*)"mon:"

成功了 谢谢
作者: wxy    时间: 2017-2-3 12:18
本帖最后由 wxy 于 2017-2-3 12:26 编辑
fcode 发表于 2017-2-2 16:07
write(*,*)"year:"
    read(*,*)year
    write(*,*)"mon:"

你好 我刚意识到一个问题,我的30个文件本身是30年的数据,如果年月日都放到循环外面,那么计算结果就把30年数据当成同一年来算了(我需要的是对30年每年的同一段日期进行计算),所以我试着把月和日放在循环外面,年份放在循环里面,这样月日只输入一次,年份每读入一个文件输入一次,但是计算结果完全不对,是不是语句改的不对,希望帮忙看一下。然后就是有没有可能更方便一点只输入起止年份刚好对应30个文件。
[Fortran] 纯文本查看 复制代码
Module typedef
  Type tdd
    Integer :: stat = 0
    Real :: tmax, tmin, total, average
  End Type tdd
End Module typedef

Integer Function daysinyear(year, mon, day)
  Integer :: year, mon, day
  Integer :: daysinmonth(12) = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
  If (((mod(year,4)==0) .And. (mod(year,100)/=0)) .Or. (mod(year,400)==0)) Then
    daysinmonth(2) = 29
  Else
    daysinmonth(2) = 28
  End If
  daysinyear = sum(daysinmonth(:mon-1)) + day
End Function daysinyear

Program main
  Use typedef
  Implicit None
  Real :: rain
  Type (tdd), Allocatable :: t(:) ! 保存气温值
  Type (tdd) :: total !日均温累加
  Integer i, m, dy, start, end, year, mon, day, daysinyear, k
  Character (Len=20) :: line, filename = 'CN174654 (12)'

  Open (8, File='result.txt')

!初始日期转换为一年的第几天

  Write (*, *) 'mon:'
  Read (*, *) mon
  Write (*, *) 'day:'
  Read (*, *) day
  Print *, daysinyear(year, mon, day)
  start = daysinyear(year, mon, day)
!结束日期转化为一年的第几天

  Write (*, *) 'mon:'
  Read (*, *) mon
  Write (*, *) 'day:'
  Read (*, *) day


  Print *, daysinyear(year, mon, day)
  end = daysinyear(year, mon, day)

!批量处理
  Do k = 1, 30
!内部文件读写, 将 filename 第 8-11 字符换为相应年份
    Write (filename(11:12), '(i2)') k
    Open (7, File=filename)
!获取行数
    i = 0
    Do
      Read (7, *, End=100) line
      i = i + 1
    End Do
    100 m = i - 1 !//跳过第一行
    Rewind (7)

    Allocate (t(m))
    Read (7, *)

    Do i = 1, m
      Read (7, *) dy, t(i)%tmax, t(i)%tmin, rain !读入数据
      t(i)%average = (t(i)%tmax+t(i)%tmin)/2 !日均温
    End Do
    total%average = 0
    Write (*, *) 'year:'
    Read (*, *) year
    Print *, daysinyear(year, mon, day)
    start = daysinyear(year, mon, day)
    end=start
!积温计算
    Do i = start, end
      total%average = total%average + t(i)%average !日均温累加=积温
    End Do
    Write (8, *) total%average ! 结果写入另一个文件

    Deallocate (t)
    Close (7)

  End Do
  Close (8)
End Program main


作者: fcode    时间: 2017-2-3 12:33
假设从 2000 年循环到 2030 年
year = 2000
do k = 1 , 30
  year = year + 1
end do
作者: wxy    时间: 2017-2-3 13:30
本帖最后由 wxy 于 2017-2-3 15:48 编辑


运行后 结果有点问题 就是30年循环 第一年的结果有点出入 其他年份都是正确的 我手动算了一下,1980年是闰年 但循环里面这一年没按闰年计算,这是什么原因
[Fortran] 纯文本查看 复制代码
Module typedef
  Type tdd
    Integer :: stat = 0
    Real :: tmax, tmin, total, average
  End Type tdd
End Module typedef

Integer Function daysinyear(year, mon, day)
  Integer :: year, mon, day
  Integer :: daysinmonth(12) = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
  If (((mod(year,4)==0) .And. (mod(year,100)/=0)) .Or. (mod(year,400)==0)) Then
    daysinmonth(2) = 29
  Else
    daysinmonth(2) = 28
  End If
  daysinyear = sum(daysinmonth(:mon-1)) + day
End Function daysinyear

Program main
  Use typedef
  Implicit None
  Real :: rain
  Type (tdd), Allocatable :: t(:) ! 保存气温值
  Type (tdd) :: total !日均温累加
  Integer i, m, dy, start, end, year, mon, day, daysinyear, k
  Character (Len=20) :: line, filename = 'CN174654 (12)'

  Open (8, File='result.txt')


!初始日期转换为一年的第几天
  Write (*, *) 'mon:'
  Read (*, *) mon
  Write (*, *) 'day:'
  Read (*, *) day
  Print *, daysinyear(year, mon, day)
  start = daysinyear(year, mon, day)
!结束日期转化为一年的第几天

  Write (*, *) 'mon:'
  Read (*, *) mon
  Write (*, *) 'day:'
  Read (*, *) day

  Print *, daysinyear(year, mon, day)
  end = daysinyear(year, mon, day)
!年份与文件年份对应
  year = 1979
!批量处理
  Do k = 1, 30
    year=year+1
!内部文件读写, 将 filename 第 8-11 字符换为相应年份
    Write (filename(11:12), '(i2)') k
    Open (7, File=filename)
!获取行数
    i = 0
    Do
      Read (7, *, End=100) line
      i = i + 1
    End Do
    100 m = i - 1 !//跳过第一行
    Rewind (7)

    Allocate (t(m))
    Read (7, *)
!积温计算
    Do i = 1, m
      Read (7, *) dy, t(i)%tmax, t(i)%tmin, rain !读入数据
      t(i)%average = (t(i)%tmax+t(i)%tmin)/2 !日均温
    End Do
    total%average = 0

!
    Do i = start, end
      total%average = total%average + t(i)%average !日均温累加=积温
    End Do
    Write (8, *) year,total%average ! 结果写入另一个文件

    Deallocate (t)
    Close (7)

  End Do
  Close (8)
End Program main

QQ截图20170203153352.png (6.26 KB, 下载次数: 247)

QQ截图20170203153352.png

QQ截图20170203153343.png (1.82 KB, 下载次数: 261)

QQ截图20170203153343.png

作者: wxy    时间: 2017-2-3 19:33
本帖最后由 wxy 于 2017-2-4 16:11 编辑
fcode 发表于 2017-2-3 12:33
假设从 2000 年循环到 2030 年
year = 2000
do k = 1 , 30
弄好了,是我没把内外循环理清,还总麻烦你,谢谢了






欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2