2014-06-20 94 views
2

我的程序在Fortran中讀取一個「未格式化」的文件。除此之外,這個文件包含一個我的程序不需要的數組,但它可能會變得很大。我想跳過這個數組。如何跳過Fortran未格式化文件中的數組?

如果是這樣的程序寫入數據:

program write 
    real :: useless(10), useful=42 

    open(123, file='foo', form='unformatted') 
    write(123) size(useless) 
    write(123) useless 
    write(123) useful 
end program write 

然後這個作品閱讀:

program read 
    integer :: n 
    real, allocatable :: useless(:) 
    real :: useful 

    open(123, file='foo', form='unformatted') 
    read(123) n 
    allocate(useless(n)) 
    read(123) useless 
    read(123) useful 

    print*, useful 
end program read 

但我想,以避免分配「無用」的陣列。我發現這個

program read2 
    integer :: n, i 
    real :: useless 
    real :: useful 

    open(123, file='foo', form='unformatted') 
    read(123) n 
    do i=1,n 
    read(123) useless 
    end do 
    read(123) useful 

    print*, useful 
end program read2 

不工作(因爲記錄的長度被寫入文件 [編輯,見francescalus'答案])。

這不是更改文件格式的選項。

回答

5

讀取比記錄中少的文件存儲單元並不是一種罪過。

program read 
    real :: useful 

    open(123, file='foo', form='unformatted') 
    read(123) 
    read(123) 
    read(123) useful 

    print*, useful 
end program read 

每個「空白」讀仍繼續爲順序訪問連接的文件前進。

作爲進一步的評論:第二次嘗試不會因爲記錄長度而失敗。由於試圖讀取單獨的記錄,因此失敗。這種差異的重要性的例子可以在許多SO帖子中找到。

1

Francescalus展示瞭如何跳過整條線。如果一行包含某些應該跳過的數據以及一些要讀取的數據,則可以重複讀取一個虛擬變量以跳過錯誤的數據。下面是一個演示這個的程序。

program write 
real :: dummy,useless(10), useful=42 
integer, parameter :: outu = 20, inu = 21 
character (len=*), parameter :: fname = "foo" 
integer :: n 
call random_seed() 
call random_number(useless) 
open(outu, file=fname, form='unformatted', action = "write") 
write(outu) size(useless) 
write(outu) useless 
write(outu) useful 
close(outu) 
open(inu, file=fname, form='unformatted', action = "read") 
read (inu) n 
read (inu) (dummy,i=1,n) 
read (inu) useful 
write (*,*) "useful = ",useful 
end program write 
相關問題