Fortran Coder

查看: 13839|回复: 8
打印 上一主题 下一主题

[文件读写] 关于批量处理文件后输出结果

[复制链接]

67

帖子

16

主题

0

精华

专家

F 币
275 元
贡献
201 点
跳转到指定楼层
楼主
发表于 2017-2-1 22:20:36 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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
分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

1958

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1341 元
贡献
565 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

沙发
发表于 2017-2-2 12:46:09 | 只看该作者
你忘了 Close 7 和 deallocate(t)

67

帖子

16

主题

0

精华

专家

F 币
275 元
贡献
201 点
板凳
 楼主| 发表于 2017-2-2 13:08:03 | 只看该作者
本帖最后由 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

1958

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1341 元
贡献
565 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

地板
发表于 2017-2-2 16:07:51 | 只看该作者
    write(*,*)"year:"
    read(*,*)year
    write(*,*)"mon:"
    read(*,*)mon
    write(*,*)"day:"
    read(*,*)day

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

close(8) 请放到循环外面。

67

帖子

16

主题

0

精华

专家

F 币
275 元
贡献
201 点
5#
 楼主| 发表于 2017-2-2 16:25:06 | 只看该作者
fcode 发表于 2017-2-2 16:07
write(*,*)"year:"
    read(*,*)year
    write(*,*)"mon:"

成功了 谢谢

67

帖子

16

主题

0

精华

专家

F 币
275 元
贡献
201 点
6#
 楼主| 发表于 2017-2-3 12:18:26 | 只看该作者
本帖最后由 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

1958

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1341 元
贡献
565 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

7#
发表于 2017-2-3 12:33:35 | 只看该作者
假设从 2000 年循环到 2030 年
year = 2000
do k = 1 , 30
  year = year + 1
end do

67

帖子

16

主题

0

精华

专家

F 币
275 元
贡献
201 点
8#
 楼主| 发表于 2017-2-3 13:30:58 | 只看该作者
本帖最后由 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

67

帖子

16

主题

0

精华

专家

F 币
275 元
贡献
201 点
9#
 楼主| 发表于 2017-2-3 19:33:03 | 只看该作者
本帖最后由 wxy 于 2017-2-4 16:11 编辑
fcode 发表于 2017-2-3 12:33
假设从 2000 年循环到 2030 年
year = 2000
do k = 1 , 30
弄好了,是我没把内外循环理清,还总麻烦你,谢谢了

您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-4-23 23:30

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表