在Fortran中,如何通过从下到上的行块将文件从一个文件写回另一个文件 [英] In Fortran, how to write backward from a file to another file by blocks of line from bottom to top

查看:168
本文介绍了在Fortran中,如何通过从下到上的行块将文件从一个文件写回另一个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASCII文件,看起来像:

I have an ASCII file that looks like:

____________________________________________
Header1 ...
Header2 ...
Header3 ...
block(1)data1 block(1)data2 block(1)data3
block(1)data4 block(1)data5 block(1)data6
block(2)data1 block(2)data2 block(2)data3
block(2)data4 block(2)data5 block(2)data6
...
block(n)data1 block(n)data2 block(n)data3
block(n)data4 block(n)data5 block(n)data6
____________________________________________

我想将其转换为如下所示的ASCII文件:

I would like to convert it into an ASCII file that looks like:

____________________________________________
HeaderA ...
HeaderB ...
block(n)data1 block(n)data2 block(n)data3
block(n)data4 block(n)data5 block(n)data6
block(n-1)data1 block(n-1)data2 block(n-1)data3
block(n-1)data4 block(n-1)data5 block(n-1)data6
....
block(1)data1 block(1)data2 block(1)data3
block(1)data4 block(1)data5 block(1)data6
____________________________________________

数据主要是实数,并且数据集的大小太大而无法使用可分配的数组.因此,我可以通过某种方式即时读写.

Data are mainly real numbers, and size of the data set is way too big to use allocatable arrays. So I have somehow to read and write on the fly.

我找不到在文件中向后读或写的方法.

I could not find a way to read-or-write backward in a file.

推荐答案

好吧,我有一个答案,但这没用,可能是由于编译器错误或我对Fortran中文件定位的基本了解.我的尝试是使用access = 'stream'form = 'formatted'打开输入文件.这样,我可以将行位置推入堆栈,然后弹出它们,以便它们以相反的顺序出现.然后,以相反的顺序遍历这些行,我可以将它们写到ourput文件中.

Well, I sort of have an answer, but it didn't work, perhaps due to compiler bugs or my rudimentary understanding of file positioning in Fortran. My attempt was to open the input file with access = 'stream' and form = 'formatted'. This way I could push the line positions onto a stack and pop them off so they come out in reverse order. Then, walking through the lines in reverse order I could write them into the ourput file.

program readblk
   implicit none
   integer iunit, junit
   integer i, size
   character(20) line
   type LLnode
      integer POS
      type(LLnode), pointer :: next => NULL()
   end type LLnode
   type(LLNODE), pointer :: list => NULL(), current => NULL()
   integer POS, temp(2)

   open(newunit=iunit,file='readblk.txt',status='old',access='stream',form='formatted')
   open(newunit=junit,file='writeblk.txt',status='replace')
   do i = 1, 3
      do
         read(iunit,'(a)',advance='no',EOR=10,size=size) line
         write(junit,'(a)',advance='no') line
      end do
10    continue
      write(junit,'(a)') line(1:size)
   end do
   do
      inquire(iunit,POS=POS)
      allocate(current)
      current%POS = POS
      current%next => list
      list => current
      read(iunit,'()',end=20)
   end do
20 continue
   current => list
   list => current%next
   deallocate(current)
   do while(associated(list))
      temp(2) = list%POS
      current => list%next
      deallocate(list)
      temp(1) = current%POS
      list => current%next
      deallocate(current)
      do i = 1, 2
write(*,*) temp(i)
         read(iunit,'(a)',advance='no',EOR=30,size=size,POS=temp(i)) line
         write(junit,'(a)',advance='no') line
         do
            read(iunit,'(a)',advance='no',EOR=30,size=size) line
            write(junit,'(a)',advance='no') line
         end do
30       continue
      write(junit,'(a)') line(1:size)
      end do
   end do
end program readblk

这是我的输入文件:

Header line 1
Header line 2
Header line 3
1a34567890123456789012345678901234567890
1b34567890123456789012345678901234567890
2a34567890123456789012345678901234567890
2b34567890123456789012345678901234567890
3a34567890123456789012345678901234567890
3b34567890123456789012345678901234567890

现在使用ifort,我的文件位置被打印为

Now with ifort my file positions were printed out as

 214
 256
 130
 172
  44
  88

请注意,第一行位于记录3的末尾,而不是记录4的开始.输出文件为

Note that the first line is at the end of record 3 instead of the beginning of record 4. The output file was

Header line 1
Header line 2
Header line 3
3a34567890123456789012345678901234567890
3b34567890123456789012345678901234567890
2a34567890123456789012345678901234567890
2b34567890123456789012345678901234567890

1a34567890123456789012345678901234567890

使用gfortran,文件位置打印为

With gfortran, the file positions printed out as

 214
 256
 130
 172
  46
  88

这一次,正如我所期望的,第一行位于记录4的开头.但是,输出文件中包含不幸的内容

This time the first line is at the beginning of record 4 as I would expect. However, the output file had unfortunate contents

Header line 1
Header line 2
Header line 3
3a34567890123456789012345678901234567890
3b34567890123456789012345678901234567890
2a34567890123456789012345678901234567890
2b34567890123456789012345678901234567890
3a34567890123456789012345678901234567890
3b345678901234567890123456789012341a34567890123456789012345678901234567890

我希望有一个更积极的结果.我无法确定结果是否是由于不良的编程或编译器错误所致,但我发布了消息,以防其他人可能使用我的纯Fortran解决方案.

I had hoped for a more positive result. I can't tell whether my results are due to poor programming or compiler bugs, but I posted in case someone else could possibly get my pure Fortran solution to work.

这篇关于在Fortran中,如何通过从下到上的行块将文件从一个文件写回另一个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆