Discussion:
How to read a text file one character at a time?
(too old to reply)
Louis Krupp
2004-10-05 18:34:08 UTC
Permalink
I am using Microsoft Fortran 4.0 (yes, I know its old, but we have a lot of
apps
written for it here at work) in a PC environment. I have the need to scan a
text file consisting of
from 1 to 80 characters per line (terminated by a cr/lf) looking for certain
character.
I am have trouble trying to figure out how to read one character at a time.
===============================================================
C Test of MicroSoft Fortran 4.0
C
PROGRAM TESTRD
CHARACTER C
WRITE(*,100)
100 FORMAT(' ** Test to read one character at a time **'//)
OPEN(10,FILE='TESTFIL.ASC')
105 READ(10,110,END=999) C
110 FORMAT(A1)
WRITE(10,120) C
120 FORMAT(1X,A1,$)
GOTO 105
999 CLOSE(10)
END
==============================================================
==============================================================
**Test to read one character at a time **
1 1 1 1 1 1 1 1
==============================================================
==============================================================
1N34
To <------)||(------>|----+-----o+
Spkr 8ohm )||( 200ohm |+ to
jack <------)||(---+ === 1uf strip chart
| | recorder
+--------+-----o -
<snip>
[and it goes on for several kilobytes]
===============================================================
Your program reads and writes unit 10. Are you sure you want to do
that? I wouldn't have expected any output at all after the ' ** Test' line.

You might want to read an array of 80 characters for each line of the
file and then loop through the array looking for the character of
interest. Someone else will have a better handle on how to tell how
many characters you've read (or that might be in your manual).

Louis Krupp
Paul Van Delst
2004-10-05 19:30:54 UTC
Permalink
I am using Microsoft Fortran 4.0 (yes, I know its old, but we have a lot of
apps
written for it here at work) in a PC environment. I have the need to scan a
text file consisting of
from 1 to 80 characters per line (terminated by a cr/lf) looking for certain
character.
I am have trouble trying to figure out how to read one character at a time.
I agree with a previous poster about reading a line at a time, rather than a character at
a time. Once you've got the line read in, you can check individual characters pretty
easily. Here is a test program I threw together to search the file for the character "+":


program Test_Read

implicit none

character*1 Select_Character
parameter ( Select_Character = '+' )

integer i
integer n_Lines
integer IO_Status
character*100 Line_Buffer

open( 10, file = 'TESTFIL.ASC',
+ form = 'FORMATTED',
+ access = 'SEQUENTIAL',
+ status = 'OLD',
+ iostat = IO_Status )

if ( IO_Status .NE. 0 ) then
write( *, '( /5x, ''Error opening test file.'' )' )
stop
end if


c --------------------------
c Open loop to read the file
c --------------------------

n_Lines = 0
100 continue
n_Lines = n_Lines + 1

c -- Read an entire line
read( 10, '(a)', iostat = IO_Status ) Line_Buffer

c -- Check for error
if ( IO_Status .GT. 0 ) then
write( *, '( /5x, ''Error reading line #'', i5 )' ) n_Lines
stop
end if

c -- Check for eof
if ( IO_Status .LT. 0 ) then
close( 10 )
goto 200
end if

c -- Scan line buffer for selected character
do i = 1, 100
if ( Line_Buffer(i:i) .EQ. Select_Character ) then
write( *, '( 10x, ''Found character '', a,
+ '' at position '', i5,
+ '' in line '', i5 )' )
+ Select_Character, i, n_Lines
end if
end do

goto 100

200 continue

end


and I use the following TESTFIL.ASC:
==============================================================
1N34
To <------)||(------>|----+-----o+
Spkr 8ohm )||( 200ohm |+ to
jack <------)||(---+ === 1uf strip chart
| | recorder
+--------+-----o -


*** Oct. 27, 1994 Integrator built.
Modified the above circuit for variable integration:


To <------)||(------>|------^v^v^v 20K trimpot
Spkr )||( ^
jack <------)||(---+ |
8/200ohm | +------+------+------+------o+
| |.01uf |.1uf +|1uf +|10uf
| === === === ===
| | | | |
| o o o o jumpers
| o o o o
| | | | |
+-------------+------+------+------+------o-

[and it goes on for several kilobytes]
===============================================================


and here is the result:

lnx:scratch : g77 test_read.f
lnx:scratch : a.out
Found character + at position 29 in line 3
Found character + at position 36 in line 3
Found character + at position 30 in line 4
Found character + at position 20 in line 5
Found character + at position 20 in line 7
Found character + at position 29 in line 7
Found character + at position 20 in line 16
Found character + at position 34 in line 17
Found character + at position 41 in line 17
Found character + at position 48 in line 17
Found character + at position 55 in line 17
Found character + at position 63 in line 17
Found character + at position 47 in line 18
Found character + at position 54 in line 18
Found character + at position 20 in line 24
Found character + at position 34 in line 24
Found character + at position 41 in line 24
Found character + at position 48 in line 24
Found character + at position 55 in line 24

Is this useful? BTW, no guarantees on the standardivity of the above test code. It's been
many years since I wrote a working f77 program.

cheers,

paulv
Richard E Maine
2004-10-05 19:53:09 UTC
Permalink
Post by Paul Van Delst
BTW, no guarantees on the standardivity of the above
test code. It's been many years since I wrote a working f77 program.
How about the standardivity of the word "standardivity"? :-)
On the other hand, maybe it is ok, even if it isn't one I've seen.
I guess it is no more awkward than "standardness", which I'm sure I've
seen. I didn't actually check either one. And no, I'm not really picking
on you about it regardless - just amused at the word. :-)

Anyway...

Several things not valid in standard f77, but at a (very) quick glance
it looked like standard f90 to me.

But MS PowerStation 4.0 did allege to be a Fortran 90 compiler and I
wouldn't expect it to have trouble with this stuff, as all the f90-isms
in it are on the trivial side (and even supported by many f77 compilers).

That compiler had plenty of problems, and I recommend ditching it, but
I doubt those problems were in the few f90 things your code uses. Now
the fact that formatted I/O is involved - there's a potential problem
area, but one that isn't particularly f90-specific.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
Kevin G. Rhoads
2004-10-05 20:24:06 UTC
Permalink
Post by Richard E Maine
But MS PowerStation 4.0 did allege to be a Fortran 90 compiler and I
I thought the OP was referring to MS Fortran Professional Development
System 4.0 (the 16 bit compiler) not MS Fortran Powerstation 4.0 (the
32 bit compiler). PDS4 was fairly decent for its time, not nearly as
buggy as FPS4. However, on re-reading I see the OP did not specify
either -- just MS 4 which could be either one. <sigh>

If FPS4 is at issue, an "upgrade" to DVF/CVF is a *good* idea.
Richard E Maine
2004-10-05 22:13:11 UTC
Permalink
Post by Kevin G. Rhoads
Post by Richard E Maine
But MS PowerStation 4.0 did allege to be a Fortran 90 compiler and I
I thought the OP was referring to MS Fortran Professional Development
System 4.0 (the 16 bit compiler) not MS Fortran Powerstation 4.0 (the
32 bit compiler)....
Hmm. I didn't even think of that one, but I bet you are right. For
some reason, I don't tend to hear much about version 4 in that old
16-bit series. A lot about 3.x and 5.x, but seldom 4.x. Don't know
why.

I've got some manuals around here somewhere... ah...there they
are...and even the original floppies. All for 5.0, but I do see that
they refer to it most places as just "Microsoft Fortran", making it
seem like at least a decent thesis that this could be the series that
the OP was talking about. I don't offhand (not that I dug deeply) see
the words "Professional Development System" in the docs I have, but I
bet it is the same series. The copyright date for 5.0 seems to be 1989.

I recall some substantial annoyances with 5.0, though details are hazy.
I ordered a copy of it and a Lahey f77 at the same time. The MS 5.0 came
in first and I spent a bit of time fighting with it until the Lahey one
came in (and worked much better for me). let's see, problems I vaguely recall

1. Something to do with COMMON that hit me all over. Perhaps not liking
to see the same COMMON twice in the same source file...even in different
subroutines. Might have related to SAVE - details forgotten.

2. Smallish limits on some things like number of subroutines in a program.

3. Unhelpful error messages that drove me wild. In fact, one vaguely related
to things in this thread. It didn't like the nonstandard $ in a format
(using "\" for the same purpose) and I'd forgotten that I had one of those
in the code. No great shock that it didn't like it, but it was a bit
annoying that it just crashed the compiler with no useful error message.
I couldn't even figure out what subroutine it was working on. I was
starting a binary search to find the problem code (cut the input file
roughtly in half and see which half crashes the compiler) when the
Lahey compiler came in. The Lahey compiler also didn't like the $ as I
recall, but it said so rather clearly. That reminded me I had used
the $, so I took that usage out, which got me past at least that problem
with MS 5.0 also.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
Kevin G. Rhoads
2004-10-05 19:02:35 UTC
Permalink
OPEN(10,FILE='TESTFIL.ASC')
The above line will open the file for SEQUENTIAL, FORMATTED access
in MS F4.0. If you need to process one character at a time you
need to do something different:
1) open for DIRECT access, RECL=1
OR
2) read a full line and process character by character internally

If you really want to use the same file for input and output, #1
is about it. But it is a *good* idea to use two files, one for
input and another for output -- then if all processing goes
well you can delete the input file and rename the output file.

Using two files, the #2 method can work very well if all your lines
have a fixed length, or variable lengths with a fixed maximum.

HTH
Kevin
Continue reading on narkive:
Loading...