reading an external text file 
Author Message
 reading an external text file

program harper3
CHARACTER(256) :: Filename
CHARACTER(100) :: content
Filename ="m16.txt"
OPEN(10,FILE=Filename,STATUS='OLD')
read(10,'(a)') content
CLOSE(10)
write (*,*) content
end program harper3
!end source
At long last, the above opens a file and retrieves data from it.  When
it hits a carriage return or a newline character in the text file, it
stops the read.  What gives?

Given that this is a single text file of modest size, wouldn't I want
to make a single read to get it all into a character array, or
whatever fortran does instead of that C vernacular*, and then pick
apart the char array as necessary?  The program is called harper3 for
reasons having to do with continuity in my own programming
environment.  John had nothing to do with the above.  He did however
recommend a book that I'm reading called _The Mathematical Sciences
Essays for COSRIMS_.  MIT Press 1969.  Fascinating.
--
Wade Ward
*I dispute Eric Sosman's reading of the word "vernacular."



Sun, 13 Dec 2009 05:35:10 GMT  
 reading an external text file

Quote:
> program harper3
> CHARACTER(256) :: Filename
> CHARACTER(100) :: content
> Filename ="m16.txt"
> OPEN(10,FILE=Filename,STATUS='OLD')
> read(10,'(a)') content
> CLOSE(10)
> write (*,*) content
> end program harper3
> !end source
> At long last, the above opens a file and retrieves data from it.  When
> it hits a carriage return or a newline character in the text file, it
> stops the read.  

Yes, that's the way Fortran "record-oriented" I/O has worked for the
last 50 years, and all the textbooks discuss this.


Sun, 13 Dec 2009 05:56:24 GMT  
 reading an external text file

Quote:

> program harper3
> CHARACTER(256) :: Filename
> CHARACTER(100) :: content
> Filename ="m16.txt"
> OPEN(10,FILE=Filename,STATUS='OLD')
> read(10,'(a)') content
> CLOSE(10)
> write (*,*) content
> end program harper3
> !end source
> At long last, the above opens a file and retrieves data from it.  When
> it hits a carriage return or a newline character in the text file, it
> stops the read.  What gives?

> Given that this is a single text file of modest size, wouldn't I want
> to make a single read to get it all into a character array, or
> whatever fortran does instead of that C vernacular*, and then pick
> apart the char array as necessary?  ...

Depends on the form of the data and what you want to do with it.

As Beliavsky notes, Fortran I/O is record-oriented as opposed to
stream-oriented for lack of a better vernacular :) for the C idiom...

Where C has a repeat on a getchar() call, in Fortran vernacular :) you
repeat on a read() statement returning the requested data into a
variable a line at a time (typically--other things are possible, but
that's the norm).

So if your data were all character (string) rather than numeric if you
include your read statement in a loop you can then process the data a
line/record at a time...

I was going to write a sample, but SWMBO just called supper, sorry... :)

--



Sun, 13 Dec 2009 07:08:38 GMT  
 reading an external text file


Quote:
>program harper3
...
>end program harper3
>!end source
>At long last, the above opens a file and retrieves data from it.  When
>it hits a carriage return or a newline character in the text file, it
>stops the read.  What gives?

>Given that this is a single text file of modest size, wouldn't I want
>to make a single read to get it all into a character array...?

The program did exactly what Wade told it to. One read statement
of the kind he used reads one line of the text file into the
variable called content, which is scalar, NOT an array, and which is
100 characters long. RTFM to see what happens if any line in the file
is under or over 100 characters.

To do what Wade now seem to be asking for requires content to be an
array. An amendment that works is the following, and it has some
simple sanity checks. I changed the file name to be the name of my
source program file, to check more easily. The reading and writing
could have been done without a DO loop, but the present version may
gives more useful output if there's a read error. Wade may look up
the implied-do syntax for himself.

program testreadarray ! in file testreadarray.f90
  CHARACTER(256) :: Filename
  CHARACTER(100) :: content(200) ! array of 200 100-character elements
  INTEGER        :: nread,i,nmax
  nmax = size(content) ! Number of elements in the array
  Filename ="testreadarray.f90"
  OPEN(10,FILE=Filename,STATUS='OLD')
  DO i = 1,nmax        ! stop reading when content is full
     read(10,'(a)',END=666,ERR=999) content(i)
! As lines < 100 long are padded with blanks, trim is used below.
     write (*,'(A)') trim(content(i))
  END DO
666 CLOSE(10)
! If no read error and the file has >= nmax lines, i will now be nmax+1
  IF(i>nmax) WRITE(*,*)'Warning: '//trim(filename)// &
       ' has more than',nmax-1,' lines.'
STOP 'No error found'
999 STOP 'Error during reading'
end program testreadarray

-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand



Sun, 13 Dec 2009 08:49:48 GMT  
 reading an external text file

Quote:


>> program harper3
>> CHARACTER(256) :: Filename
>> CHARACTER(100) :: content
>> Filename ="m16.txt"
>> OPEN(10,FILE=Filename,STATUS='OLD')
>> read(10,'(a)') content
>> CLOSE(10)
>> write (*,*) content
>> end program harper3
>> !end source
>> At long last, the above opens a file and retrieves data from it.  When
>> it hits a carriage return or a newline character in the text file, it
>> stops the read.  What gives?

>> Given that this is a single text file of modest size, wouldn't I want
>> to make a single read to get it all into a character array, or
>> whatever fortran does instead of that C vernacular*, and then pick
>> apart the char array as necessary?  ...

> Depends on the form of the data and what you want to do with it.

> As Beliavsky notes, Fortran I/O is record-oriented as opposed to
> stream-oriented for lack of a better vernacular :) for the C idiom...

> Where C has a repeat on a getchar() call, in Fortran vernacular :) you
> repeat on a read() statement returning the requested data into a
> variable a line at a time (typically--other things are possible, but
> that's the norm).

> So if your data were all character (string) rather than numeric if you
> include your read statement in a loop you can then process the data a
> line/record at a time...

OK, it's now morning and I'm tied here waiting for a call, so on the
assumption it's still of interest...

Something like the following would allow you to process the data as it
is read if the algorithm for whatever processing you are doing doesn't
require more than the current observation simultaneously.  This has the
advantage of minimal memory usage w/ the disadvantage of (obviously) not
the previous data no longer being available after the loop if other
things are desired/needing to be done.

program harper3
   CHARACTER(256) :: Filename
   CHARACTER(100) :: content
   INTEGER        :: ios

   Filename ="m16.txt"
   OPEN(10,FILE=Filename,STATUS='OLD')

   ios = 0  ! initialize status to ok
   do
     read(10,'(a)', iostat=ios) content
     ! check for eor/eof or error condition
     if(ios<0)then
       write(*,*) 'EOR/EOR encountered.  Terminating.'
       close(10)
       exit
     elseif (ios>0) then
       write(*,*) 'Error reading record.  Terminating.'
       close(10)
       exit
     endif

     ! If here, no error so do whatever w/ content here
     call my_proc_routine(content)
     write (*,*) content
   enddo
end program harper3

If you need to process multiple records at a time, then make your
variable into an array and read into the elements of the array.  In that
case you would undoubtedly want to bring the call to my_proc_routine()
outside the loop.

There are, of course, as many variations on a theme as there are users... :)

Similar examples should be readily available in any text or even in the
supplied examples from various compilers.

HTH...the phone just rang so above not tested for typos, etc., ...

--



Sun, 13 Dec 2009 22:12:39 GMT  
 reading an external text file

<snip>

Quote:
> Something like the following would allow you to process the data as it
> is read if the algorithm for whatever processing you are doing doesn't
> require more than the current observation simultaneously.  This has the
> advantage of minimal memory usage w/ the disadvantage of (obviously) not
> the previous data no longer being available after the loop if other
> things are desired/needing to be done.

The disadvantages of the methods you and Mr. Harper illustrated are
that
(1) lines shorter than 100 characters are padded with blanks and
(2) (more seriously) lines longer than 100 characters are truncated.

I use the same method in my codes and don't intend the above as
criticism. Memory is cheap enough that I typically make the character
variable a factor of 10 larger than what I think is needed.

Quote:

> program harper3
>    CHARACTER(256) :: Filename
>    CHARACTER(100) :: content
>    INTEGER        :: ios

>    Filename ="m16.txt"
>    OPEN(10,FILE=Filename,STATUS='OLD')

>    ios = 0  ! initialize status to ok
>    do
>      read(10,'(a)', iostat=ios) content
>      ! check for eor/eof or error condition
>      if(ios<0)then
>        write(*,*) 'EOR/EOR encountered.  Terminating.'
>        close(10)
>        exit
>      elseif (ios>0) then
>        write(*,*) 'Error reading record.  Terminating.'
>        close(10)
>        exit
>      endif

>      ! If here, no error so do whatever w/ content here
>      call my_proc_routine(content)
>      write (*,*) content
>    enddo
> end program harper3

<snip>


Mon, 14 Dec 2009 01:36:41 GMT  
 reading an external text file

Quote:

> <snip>

> > Something like the following would allow you to process the data as it
> > is read if the algorithm for whatever processing you are doing doesn't
> > require more than the current observation simultaneously.  This has the
> > advantage of minimal memory usage w/ the disadvantage of (obviously) not
> > the previous data no longer being available after the loop if other
> > things are desired/needing to be done.

> The disadvantages of the methods you and Mr. Harper illustrated are
> that
> (1) lines shorter than 100 characters are padded with blanks and
> (2) (more seriously) lines longer than 100 characters are truncated.

> I use the same method in my codes and don't intend the above as
> criticism. Memory is cheap enough that I typically make the character
> variable a factor of 10 larger than what I think is needed.

[code snipped]
Thanks all for replies.  I'm certain that there is enough there to get
some of the minimal functionality I seek.  If you did a while loop
with a read statement in it s.t. you would have enough reads to get to
EOF, if you wrote to a file with lun = 11 and Status=New, but with
otherwise the same read/write specification, what you read on ten,
would the files be the same?  Gosh, that's unpretty English.
(Probably unmgrammatical too.)

Let me rephrase.  Let the open statement include using the IOstatus
specifier.  If I loop through on a while statement until IOStatus is
negative, will I get the whole file?
--
Wade Ward
--
Wade Ward



Mon, 14 Dec 2009 05:50:28 GMT  
 reading an external text file

Quote:



>> <snip>

>>> Something like the following would allow you to process the data as it
>>> is read if the algorithm for whatever processing you are doing doesn't
>>> require more than the current observation simultaneously.  This has the
>>> advantage of minimal memory usage w/ the disadvantage of (obviously) not
>>> the previous data no longer being available after the loop if other
>>> things are desired/needing to be done.
>> The disadvantages of the methods you and Mr. Harper illustrated are
>> that
>> (1) lines shorter than 100 characters are padded with blanks and
>> (2) (more seriously) lines longer than 100 characters are truncated.

>> I use the same method in my codes and don't intend the above as
>> criticism. Memory is cheap enough that I typically make the character
>> variable a factor of 10 larger than what I think is needed.
> [code snipped]
> Thanks all for replies.  I'm certain that there is enough there to get
> some of the minimal functionality I seek.  If you did a while loop
> with a read statement in it s.t. you would have enough reads to get to
> EOF, if you wrote to a file with lun = 11 and Status=New, but with
> otherwise the same read/write specification, what you read on ten,
> would the files be the same?  Gosh, that's unpretty English.
> (Probably unmgrammatical too.)

> Let me rephrase.  Let the open statement include using the IOstatus
> specifier.  If I loop through on a while statement until IOStatus is
> negative, will I get the whole file?

The IOSTATUS specifier is on the READ, not the OPEN to ascertain EOF
while reading the file.  Not sure what you have in mind precisely w/ the
OPEN.  'NEW' or 'UNKNOWN' and "WRITE" for the second file are
significant, perhaps.

If the READ iostatus negative is an EOF and not an EOR, yes.  EOR could
occur if an individual record was longer than the variable allocated
(Beliavisky's complaint/comment).  Other than that error, the code loop
I gave if it included

write(11,'(A)') content

where you have write(*,*) would be, in essence, "copy filea fileb" at a
DOS prompt...note that Fortran I/O will, by default, write the
appropriate for the OS newline sequence transparently -- that's part of
the record-based i/o paradigm as opposed to C stream i/o.  (Not
better/worse, just different.)

There is a possible difference in that Fortran uses fixed-length
character variables so if the source file is variable length records
unless you TRIM() the data as it is written to the output file each line
will be the same length as the defined character variable (100 in your
example iirc).

There's the possible complication of trying to read a Unix-ish system
file on a Windows system, but ignoring that the two should be the same
w/ the above caveat.

hth...

--



Mon, 14 Dec 2009 06:13:08 GMT  
 reading an external text file

Quote:

> EOR could
> occur if an individual record was longer than the variable allocated...

No, that's not what EOR is about. EOR is relevant only to non-advancing
I/O.

--
Richard Maine                    | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle           |  -- Mark Twain



Mon, 14 Dec 2009 06:39:04 GMT  
 reading an external text file


Quote:


>>program harper3
> ...
>>end program harper3
>>!end source
>>At long last, the above opens a file and retrieves data from it.  When
>>it hits a carriage return or a newline character in the text file, it
>>stops the read.  What gives?

>>Given that this is a single text file of modest size, wouldn't I want
>>to make a single read to get it all into a character array...?

> The program did exactly what Wade told it to. One read statement
> of the kind he used reads one line of the text file into the
> variable called content, which is scalar, NOT an array, and which is
> 100 characters long. RTFM to see what happens if any line in the file
> is under or over 100 characters.

> To do what Wade now seem to be asking for requires content to be an
> array. An amendment that works is the following, and it has some
> simple sanity checks. I changed the file name to be the name of my
> source program file, to check more easily. The reading and writing
> could have been done without a DO loop, but the present version may
> gives more useful output if there's a read error. Wade may look up
> the implied-do syntax for himself.

program harper2
 CHARACTER(*), PARAMETER :: FMTSTRING = '("m",i0,".txt")'
   CHARACTER(256) :: Filename
   INTEGER :: i, n_Files

   n_Files = 85

   DO i = 1, n_Files
     WRITE(Filename,FMT=FMTSTRING) i
     write (*,*) trim(Filename)
!    OPEN(10,FILE=Filename,STATUS='OLD')
!     ...do something with file
     CLOSE(10)
   END DO

end program harper2

program harper5
! was  testreadarray.f90 John Harper
  CHARACTER(256) :: Filename
  CHARACTER(100) :: content(200) ! array of 200 100-character elements
  INTEGER        :: i,nmax
  nmax = size(content) ! Number of elements in the array
  Filename ="m16.txt"
  OPEN(10,FILE=Filename,STATUS='OLD')
  DO i = 1,nmax        ! stop reading when content is full
     read(10,'(a)',END=666,ERR=999) content(i)
! As lines < 100 long are padded with blanks, trim is used below.
     write (*,'(A)') trim(content(i))
  END DO
666 CLOSE(10)
! If no read error and the file has >= nmax lines, i will now be nmax+1
  IF(i>nmax) WRITE(*,*)'Warning: '//trim(filename)// &
       ' has more than',nmax-1,' lines.'
STOP 'No error found'
999 STOP 'Error during reading'
end program harper5
! end source
I'm at the point where I'm going to combine the above progs.  Having n_Files
hard coded at 85 is what I need.  Furthermore, 200 100-character arrays are
appropriate for what I'm going after.  There is one thing I want to add.  In
pseudo code:
if (the first character of content(i) == '>')
then continue
else    write (*,'(A)') trim(content(i))
endif
How do I write that in fortran?
--
Wade Ward



Tue, 15 Dec 2009 02:39:09 GMT  
 reading an external text file
[...]

Quote:
> I'm at the point where I'm going to combine the above progs.  Having n_Files
> hard coded at 85 is what I need.  Furthermore, 200 100-character arrays are
> appropriate for what I'm going after.  There is one thing I want to add.  In
> pseudo code:
> if (the first character of content(i) == '>')
> then continue
> else    write (*,'(A)') trim(content(i))
> endif
> How do I write that in fortran?

You nearly have it as is. :-)  You need to use a test on
a substring of content(i) (and I'd reverse the sense of
the test to avoid the empty block before the "else":

if (content(i)(1:1) /= '>')  ! Test first character not equal to ">"
then
    write (*, '(A)') trim(content(i))
endif

OK?

     -Ken
--
Ken & Ann Fairfield
What:  Ken dot And dot Ann
Where: Gmail dot Com



Tue, 15 Dec 2009 02:58:00 GMT  
 reading an external text file


Quote:

> [...]
>> I'm at the point where I'm going to combine the above progs.  Having
>> n_Files hard coded at 85 is what I need.  Furthermore, 200 100-character
>> arrays are appropriate for what I'm going after.  There is one thing I
>> want to add.  In pseudo code:
>> if (the first character of content(i) == '>')
>> then continue
>> else    write (*,'(A)') trim(content(i))
>> endif
>> How do I write that in fortran?

> You nearly have it as is. :-)  You need to use a test on
> a substring of content(i) (and I'd reverse the sense of
> the test to avoid the empty block before the "else":

> if (content(i)(1:1) /= '>')  ! Test first character not equal to ">"
> then
>    write (*, '(A)') trim(content(i))
> endif

> OK?

My compiler complains if I don't have the 'then' on the same line as the if,
but it works like a charm.
--
Wade Ward


Tue, 15 Dec 2009 04:03:50 GMT  
 reading an external text file

Quote:



> > if (content(i)(1:1) /= '>')  ! Test first character not equal to ">"
> > then
> >    write (*, '(A)') trim(content(i))
> > endif
> My compiler complains if I don't have the 'then' on the same line as the if,
> but it works like a charm.

You compiler is correct to complain. Either that or, since there is only
a single statement to be executed when the condition is true, you can
shorten the whole thing to just

  if (content(i)(1:1) /= '>') write (*, '(A)') trim(content(i))

Either works. Some people prefer the style of aloways using the longer
form. Other people like to use the shorter form where it fits.

--
Richard Maine                    | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle           |  -- Mark Twain



Tue, 15 Dec 2009 04:30:58 GMT  
 reading an external text file


Quote:



>> > if (content(i)(1:1) /= '>')  ! Test first character not equal to ">"
>> > then
>> >    write (*, '(A)') trim(content(i))
>> > endif

>> My compiler complains if I don't have the 'then' on the same line as the
>> if,
>> but it works like a charm.

> You compiler is correct to complain. Either that or, since there is only
> a single statement to be executed when the condition is true, you can
> shorten the whole thing to just

>  if (content(i)(1:1) /= '>') write (*, '(A)') trim(content(i))

> Either works. Some people prefer the style of aloways using the longer
> form. Other people like to use the shorter form where it fits.

program harper6
CHARACTER(100) :: content(200)
INTEGER        :: i,nmax
CHARACTER(*), PARAMETER :: FMTSTRING = '("m",i0,".txt")'
CHARACTER(256) :: Filename
INTEGER ::  n_Files, j
integer, dimension(85) :: age

n_Files = 5
nmax = size(content)
DO j = 1, n_Files
  WRITE(Filename,FMT=FMTSTRING) j
  OPEN(10,FILE=Filename,STATUS='OLD')
    DO i = 1,nmax
      read(10,'(a)',END=666,ERR=999) content(i)
      if (content(i)(1:1) /= '>')  then
      write (*, '(A)') trim(content(i))
      endif
    END DO
  666 CLOSE(10)
  write (*,'(a)', advance='no') "How old is this cat? "
  read (*, '(i2)') age(j)
end do

  IF(i>nmax) WRITE(*,*)'Warning: '//trim(filename)// &
       ' has more than',nmax-1,' lines.'
STOP 'No error found'
999 STOP 'Error during reading'
end program harper6
I like the concise form for the if statement when it's as simple as the one
in question.

I have 2 forms of input in this program now.  One is from 10, the other the
keyboard.  Normally, I would run the executable and redirect the output by
using a dos window and typing harper6 >text3.txt .  I would instead like to
write it to a file using fortran.  How do I write this to a file, say,
output1.txt, giving it permission to write over any previous output1.txt ?
--
Wade Ward



Tue, 15 Dec 2009 04:48:42 GMT  
 reading an external text file

Quote:




>>> <snip>

>>>> Something like the following would allow you to process the data as it
>>>> is read if the algorithm for whatever processing you are doing doesn't
>>>> require more than the current observation simultaneously.  This has the
>>>> advantage of minimal memory usage w/ the disadvantage of (obviously)
>>>> not
>>>> the previous data no longer being available after the loop if other
>>>> things are desired/needing to be done.
>>> The disadvantages of the methods you and Mr. Harper illustrated are
>>> that
>>> (1) lines shorter than 100 characters are padded with blanks and
>>> (2) (more seriously) lines longer than 100 characters are truncated.

>>> I use the same method in my codes and don't intend the above as
>>> criticism. Memory is cheap enough that I typically make the character
>>> variable a factor of 10 larger than what I think is needed.

Since the files came off of usenet, you wouldn't expect them to be more than
what, 75 characters per record?  Which character specifically determines end
of record?

- Show quoted text -

Quote:
>> Let me rephrase.  Let the open statement include using the IOstatus
>> specifier.  If I loop through on a while statement until IOStatus is
>> negative, will I get the whole file?

> The IOSTATUS specifier is on the READ, not the OPEN to ascertain EOF while
> reading the file.  Not sure what you have in mind precisely w/ the OPEN.
> 'NEW' or 'UNKNOWN' and "WRITE" for the second file are significant,
> perhaps.

> If the READ iostatus negative is an EOF and not an EOR, yes.  EOR could
> occur if an individual record was longer than the variable allocated
> (Beliavisky's complaint/comment).  Other than that error, the code loop I
> gave if it included

> write(11,'(A)') content

> where you have write(*,*) would be, in essence, "copy filea fileb" at a
> DOS prompt...note that Fortran I/O will, by default, write the appropriate
> for the OS newline sequence transparently -- that's part of the
> record-based i/o paradigm as opposed to C stream i/o.  (Not better/worse,
> just different.)

> There is a possible difference in that Fortran uses fixed-length character
> variables so if the source file is variable length records unless you
> TRIM() the data as it is written to the output file each line will be the
> same length as the defined character variable (100 in your example iirc).

> There's the possible complication of trying to read a Unix-ish system file
> on a Windows system, but ignoring that the two should be the same w/ the
> above caveat.

I'm now able to read the messages in this thread much more closely because
I'm no longer shackled by lack of internet connection.  A person can get by
for a week going to the library and elbowing out the bums and the {*filter*}s
in order to get comment from a newsgroup through the google portal.  Doing
it for over a month goes from austerity to privation.

I was able to use the trim() function to my benefit for the first time
yesterday.  I'll take another look at your upthread source.
--
Wade Ward



Tue, 15 Dec 2009 05:19:25 GMT  
 
 [ 28 post ]  Go to page: [1] [2]

 Relevant Pages 

1. reading text from external files

2. fortran program reading an external text (and numbers) file and writing with edits

3. How do I read lines of Text from Text File and add them to Array

4. Reading fortran text files / Parsing ascii files/ Help!!

5. reading in external file in clarion4 eval

6. Reading External .txt files in Quartus II

7. reading variables from an external file using expect

8. (Newbie) Reading Text Files....

9. Reading data from a text file to store in a collection

10. VW: Reading text from Word 97 files

11. Reading arguements from the text file with irregular formats

12. Reading from a text file

 

 
Powered by phpBB® Forum Software