Reputation: 971
Suppose I have a text file with potentially very long lines of text, for example
short
short
reeeeeeeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaally loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooonnnnggg
short as well
short
I can write a simple program which reads this file:
program main
implicit none
integer, parameter :: BIG_NUMBER = 400
integer :: lun
character(len=BIG_NUMBER) :: line
integer :: istat
open(newunit = lun, file = 'myfile')
do
read (lun, '(A)', iostat = istat) line
if (istat /= 0) exit
end do
end program main
This only supports text files, where all lines are not longer than 400 characters. In C, pointers are used and a similar program would automatically support any text file.
How can I rewrite the sample program in such a way that it can read lines of all lengths?
Upvotes: 3
Views: 2584
Reputation: 21431
You can use non-advancing input to read successive chunks of the line into a buffer, and then combine each chunk together to form the complete line in a deferred length character variable. For example:
subroutine get_line(lun, line, iostat, iomsg)
integer, intent(in) :: lun
character(len=:), intent(out), allocatable :: line
integer, intent(out) :: iostat
character(*), intent(inout) :: iomsg
integer, parameter :: buffer_len = 80
character(len=buffer_len) :: buffer
integer :: size_read
line = ''
do
read ( lun, '(A)', &
iostat = iostat, &
iomsg = iomsg, &
advance = 'no', &
size = size_read ) buffer
if (is_iostat_eor(iostat)) then
line = line // buffer(:size_read)
iostat = 0
exit
else if (iostat == 0) then
line = line // buffer
else
exit
end if
end do
end subroutine get_line
Upvotes: 7
Reputation: 4656
Never seek another solution when you have one at hand, unless it has some limitations. Since you can do it in C and with all the interoperability stuff between C and Fortran, I suggest you write a small part of the program in C to handle the reading. The C part can be as simple as a set of 2 functions and few global variables:
If you are using getline
for example, the global variables will be the File object, the line buffer and the buffer size. In addition, you can add two other functions to be called by fortran to open and close the file, or you can handle all of that in the query function.
Upvotes: 1