回 帖 发 新 帖 刷新版面

主题:[讨论]关于fortran读取各行长度不一格式不一具体行数不知数据文件的思考

iwanfly网友曾在一段时间前发过贴探讨过这个问题
http://bbs.pfan.cn/post-312402.html

当时思路不是很清晰
现思考结果如下,虽然比较麻烦,但最终还是解决了读取数据的问题,前提是知道每行最大的数据个数,比如7个。
不知道论坛上的网友是否有更好的方法,不吝赐教。

测试数据如下:
12  89  77
12  999 878  777
398 789 765 98 765
78 89
12  89  77
12  999 878  777
398 789 765 98 765
。。。。
总共78144行。大概需要5,6秒时间把数据全部读进。

program main
implicit none
integer,allocatable :: int_array(:,:),temp_array(:,:)
integer :: count,length,step,i,ierr
character*256 :: str_one_record
open(100,file='data.txt')

count=0
step=100000
length=step

allocate(int_array(length,7))

int_array=0
do while(.not. eof(100))
    count=count+1
    
loop1:  do i=7,1,-1
          read(100,'(A)',advance='no',eor=168) str_one_record
168       read(str_one_record,*,end=999) int_array(count,1:i)  
          exit loop1
999       backspace 100
          int_array(count,1:i)=0  
        end do loop1
    
    if(mod(count,step)==0) then
        allocate(temp_array(length,7))
        temp_array=0
        temp_array=int_array
        deallocate(int_array)
        length=length+step
        allocate(int_array(length,7))
        int_array=0
        int_array(1:length-step,:)=temp_array
        deallocate(temp_array)
    end if
    
end do

allocate(temp_array(length,7))
temp_array=0
temp_array=int_array
deallocate(int_array)
allocate(int_array(count,7))
int_array=0
int_array(1:count,:)=temp_array(1:count,:)
deallocate(temp_array)

!下面处理int_array中数据


deallocate(int_array)
close(100)

pause
end program main


回复列表 (共15个回复)

11 楼

advance='no' 不换行 eor是end of record 读取数据直到一个记录也就是一行的末尾
str_one_record是内部文件
end=999是指读到文件末尾时跳到标签999
这时int_array(count,1:i)元素的个数大于str_one_record中数据个数
所以要backspace重新读取数据
下次读取i-1个数据
以此类推直到str_one_record中数据个数刚好等于int_array(count,1:i)元素的个数

12 楼

其实在fortran 90里面还有一种判断是否是文件结束的方法:iostat
read(lunit,1000,iostat=k)A
这句表示按照标号1000的格式说明行读取lunit对应的文件,并将读取的状态(iostat)赋值给k。
当k=-1时,就是文件结束了。这样可以省去goto 类写法,毕竟这种东西一多,代码的可读性就变差了。

13 楼

波克城市免费下载 波克城市官网免费下载 波克城市下载注册 波克城市大厅 波克城市游戏帐号注册
   
  波克城市:免费玩游戏,赢元宝,换大奖 
  波克城市游戏简介:一款让人身临其境赛3D式的2D游戏大厅平台真正公正公平且具有地方特色的专业棋牌平台,目前已开发了:游戏城市斗地主、梭哈,斗CT麻将、诈金花、上海麻将、 四国军棋等多款游戏,后续开发的游戏会不断更新。
     
  波克城市授权方式:免费下载游戏
  波克城市游戏奖品介绍:移动充值卡,手机,笔记本电脑,数码相机,MP3,等多样商品。
     
  波克城市游戏下载注册地址,请复制下面链接进入官方下载:(游戏大厅版本随时更新) 
 [size=5] http://www.gc73.com/register.do?s=75616987[/size]     
  波克城市大厅下载,游戏帐号注册流程:
   1、先进入官网注册游戏帐号。
   2、注册完游戏帐号,出现最新版游戏大厅下载地址(游戏大厅版本随时更新)。3、填写密码保护,完成后就可以玩游戏了。

14 楼


do while(.not. eof(100)) 中的eof(100)是什么意思啊?

15 楼

我用直接读取二进制文件的方式,读取了文件的大小。
下面是程序
!****************************************************************************
!
!  子程序: GetFileSize(FileName)
!
!  作用:  读取文件Filename的大小, 赋值给FileSize, 文件名赋值给FileName
!
!****************************************************************************
subroutine GetFileSize(FileName)
    implicit none
    integer,parameter::BLOCK_SIZE=1024
    integer::Status=0
    integer*8::Pos=0
    logical alive
    character(len=256)::FileName
    inquire(file=FileName, exist=alive)
    if(alive) then
        open(100,file=FileName,form="unformatted",access="direct",recl=BLOCK_SIZE)
        do while(Status==0)
            Pos=Pos+1
            read(100,rec=Pos,iostat=Status)
            if(Status>0) then
                if(Pos==1) then
                    Pos=0
                elseif(Pos>1) then
                    Pos=(Pos-2)*BLOCK_SIZE+1
                end if
                Status=0
                close(100)
                open(100,file=Filename,form="unformatted",access="direct",recl=1)
                do while(Status==0)
                    Pos=Pos+1
                    read(100,rec=Pos,iostat=Status)
                    if(Status>0) then
                        File_Size=Pos-1
                        close(100)
                    end if
                end do
            end if
        end do
    else
        write(*,*) Filename,"不存在!"
        return
    end if
end subroutine

我来回复

您尚未登录,请登录后再回复。点此登录或注册