Home > Archive > Fortran > May 2004 > How to read data from the ascii file?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
How to read data from the ascii file?
|
|
|
| Hi guys there:
I have a small question about how to read data from the ascii file
in Fortran. The problem is that I would like to read data from one
file like following:
ALS 23 20.000 0.000 100
GTA 23 35.000 -3.506 100
LAB 23 22.000 0.000 100
LAB002 23 58.004 -51.746 150
LAB004 23 14.004 2.870 150
LAB006 23 3.004 4.501 150
LAB008 48 21.004 -69.501 150
LAB010 23 12.004 -3.654 150
LAB012 23 21.333 2.271 150
LAB014 23 12.004 0.000 150
LAB015 23 9.004 3.577 150
LAB016 23 25.004 -3.111 150
LAB017 23 19.004 4.519 150
LAB019 23 17.004 6.207 150
LAB022 23 20.004 0.000 150
LAB023 23 16.003 13.791 150
LAB024 46 59.000 2.053 100
LAB025 46 56.000 5.930 100
....
....
I would like to assign the first field to a character variable and the
second and last one to integer variables, the third and fourth to
float variable. The delimiter between the field is the "TAB" instead
of spaces. So I don't know how to tell the fortran to recognize it.
Yes, I can do this using korn shell but I need more accuracy and
speed. I wrote a program to read it but does not work. Can anyone tell
me where is my wrong? Thanks in advance!
program readdata
integer count
character filename
character(len=6) stn
write(*,*) "please input the file name"
read(*,*) filename
open(7,file=filename,status='old')
1 read(7,100,end=200) site,minute,second,cor_second,sample
100 format(a6,2x,i2,6x,f6.3,2x,f7.3,1x,i3)
go to 1
200 continue
close(6)
stop
end
| |
| Dick Hendrickson 2004-05-12, 9:09 pm |
| You've got a bunch of problems here. Some mechanical,
and one technical. the technical one, Fortran doesn't
recognize tab characters, and even if it did, it wouldn't
give different spacing for different tabs. So, can
you easily replace the tabs with what you want at the
shell level? If so, skip the following discussion
about internal reads etc and just go down to the
Fortran code.
To internally change the tabs to spaces in your program:
declare a character variable big enough to hold the entire
line, something like
character(len=120) :: line
and change the read statement to read into line
1 read(7,*, end = 200) line
! the * will read it as a character string, you don't
need a format
and then process "line" to remove the tabs. You'll need
to find out what the numeric value of the tab character
is on your machine. One way to do this is to print out
the numeric values of each character in a lione and
identify the tab by counting in. Something like
do I = 1,120
Print *, I, ">>", line(I:I),"<<", ICHAR(line(I:I)
enddo
You'll only need to do this once (unless you forget
the value ;-) )
Once you know the tab value, loop through line and change
each tab into a space (you won't need to turn them into
multiple spaces)
Do I = 1,120
(If (ICHAR(line(I:I)) == magic_tab_number)
line(I:I) = ' '
enddo
At this point, you'll have a line with at least one space
between each field; the same as you'd have if you change
the tabs from the shell.
Now, you'll need to fix you program.
andy wrote:
> Hi guys there:
> I have a small question about how to read data from the ascii file
> in Fortran. The problem is that I would like to read data from one
> file like following:
>
> ALS 23 20.000 0.000 100
> GTA 23 35.000 -3.506 100
> LAB 23 22.000 0.000 100
> LAB002 23 58.004 -51.746 150
> LAB004 23 14.004 2.870 150
> LAB006 23 3.004 4.501 150
> LAB008 48 21.004 -69.501 150
> LAB010 23 12.004 -3.654 150
> LAB012 23 21.333 2.271 150
> LAB014 23 12.004 0.000 150
> LAB015 23 9.004 3.577 150
> LAB016 23 25.004 -3.111 150
> LAB017 23 19.004 4.519 150
> LAB019 23 17.004 6.207 150
> LAB022 23 20.004 0.000 150
> LAB023 23 16.003 13.791 150
> LAB024 46 59.000 2.053 100
> LAB025 46 56.000 5.930 100
> ...
> ...
> I would like to assign the first field to a character variable and the
> second and last one to integer variables, the third and fourth to
> float variable. The delimiter between the field is the "TAB" instead
> of spaces. So I don't know how to tell the fortran to recognize it.
> Yes, I can do this using korn shell but I need more accuracy and
> speed. I wrote a program to read it but does not work. Can anyone tell
> me where is my wrong? Thanks in advance!
>
> program readdata
> integer count
you need to declare minute and sample as integers
YOU SHOULD ALWAYS PUT AN IMPLICIT NONE IN YOUR CODES!!!!!!
> character filename
This limits filename to one character, probably not what you
want. Maybe character(len=25) :: filename ??
> character(len=6) stn
did you mean "site"??
> write(*,*) "please input the file name"
> read(*,*) filename
> open(7,file=filename,status='old')
> 1 read(7,100,end=200) site,minute,second,cor_second,sample
replace this with a list directed read
1 read(7,*,end-200) site, minute, second, second_cor,
sample
if you've changed the file from the shell
or with
1 read(line,*,end-200) site, minute, second,
second_cor, sample
to do an "internal read" from the line character variable if
you've used the fortran way to replace the tabs with blanks.
> 100 format(a6,2x,i2,6x,f6.3,2x,f7.3,1x,i3)
> go to 1
> 200 continue
> close(6)
It's harmless to close(6); but you opened 7 above.
Anyhow, that's all I've seen on a quick read. Good luck
on the final.
Dick Hendrickson
> stop
> end
| |
| glen herrmannsfeldt 2004-05-12, 9:09 pm |
| andy wrote:
> Hi guys there:
> I have a small question about how to read data from the ascii file
> in Fortran. The problem is that I would like to read data from one
> file like following:
>
> ALS 23 20.000 0.000 100
> GTA 23 35.000 -3.506 100
> LAB 23 22.000 0.000 100
(snip)
> The delimiter between the field is the "TAB" instead
> of spaces. So I don't know how to tell the fortran to recognize it.
I believe the TAB characters are your problem, assuming you
did everything else right.
Find a program to convert tabs to the appropriate number
of spaces, and see what happens.
While the posted data looks right, it does seem to have tabs.
-- glen
| |
| Steven G. Kargl 2004-05-12, 9:09 pm |
| In article <3Dboc.79247$Xj6.1327930@bgtnsc04-news.ops.worldnet.att.net>,
Dick Hendrickson <dick.hendrickson@att.net> writes:
>
> To internally change the tabs to spaces in your program:
> declare a character variable big enough to hold the entire
> line, something like
> character(len=120) :: line
> and change the read statement to read into line
> 1 read(7,*, end = 200) line
> ! the * will read it as a character string, you don't
> need a format and then process "line" to remove the tabs.
Are you sure this works without the quotes?
The <tab> character isn't a member of the Fortran
90 character set. Can a Fortran processor choose
to treat <tab> as <space>? At lesat NAG's compiler
appears to equate <tab> and <space>
ALS<tab>23<tab>20.000<tab>0.000<tab>100
--
Steve
http://troutmask.apl.washington.edu/~kargl/
| |
| James Giles 2004-05-12, 9:09 pm |
| Steven G. Kargl wrote:
> In article <3Dboc.79247$Xj6.1327930@bgtnsc04-news.ops.worldnet.att.net>,
> Dick Hendrickson <dick.hendrickson@att.net> writes:
>
> Are you sure this works without the quotes?
>
> The <tab> character isn't a member of the Fortran
> 90 character set. Can a Fortran processor choose
> to treat <tab> as <space>? At lesat NAG's compiler
> appears to equate <tab> and <space>
>
> ALS<tab>23<tab>20.000<tab>0.000<tab>100
If the implementation treats the tab as a space, then
the original problem wouldn't have existed. The
original program could have used list-directed reads
to start with. If the implementation treats the tab as
some non-delimiting character, then the method Dick
recommends will likely work. I would have
recommended:
character(120) :: line
...
1 read(7,'(A)',end=200) line
--
J. Giles
| |
| Kamaraju Kusumanchi 2004-05-12, 9:09 pm |
| glen herrmannsfeldt wrote:
> I believe the TAB characters are your problem, assuming you
> did everything else right.
>
> Find a program to convert tabs to the appropriate number
> of spaces, and see what happens.
>
> While the posted data looks right, it does seem to have tabs.
>
> -- glen
>
If you have access to vim editor you can do this in one command.
vim filename.f90
For interactive replacement of tabs and spaces with a single space use
%s/\s\+/ /gc
for non-interactive replacement use
%s/\s\+/ /g
hth
raju
| |
| glen herrmannsfeldt 2004-05-12, 9:09 pm |
| Kamaraju Kusumanchi wrote:
I wrote:
(snip)
[color=darkred]
> If you have access to vim editor you can do this in one command.
> vim filename.f90
> For interactive replacement of tabs and spaces with a single space use
> %s/\s\+/ /gc
> for non-interactive replacement use
> %s/\s\+/ /g
To do input using a FORMAT, one should replace the tabs with the
appropriate number of spaces so that the data agrees with
the FORMAT. I believe that is every eight columns, as
popularized by DEC systems.
As far as I know, list directed input requires apostrophes
(or maybe quotes) around CHARACTER data, so it can't be used
with this input file.
-- glen
| |
| James Giles 2004-05-12, 9:09 pm |
| glen herrmannsfeldt wrote:
....
> As far as I know, list directed input requires apostrophes
> (or maybe quotes) around CHARACTER data, so it can't be used
> with this input file.
List directed requires quotes or apostrophes only if the
values being read contain characters that would otherwise
be considered delimiters or otherwise have special meaning
in list directed (like, if the string begins with digits followed
by an asterisk). That doesn't appear to be the case in the
example data given. So, list directed should work fine
provided the tab problem is resolved.
Note: this is the F90 rule. F77 did indeed require list
directed character input to be enclosed in apostrophes.
But, since the original article in this thread used F90
syntax, I think we can assume that the F90 rule applies.
--
J. Giles
| |
| James Van Buskirk 2004-05-12, 9:09 pm |
| "andy" <andylcx@hotmail.com> wrote in message
news:16c9ae76.0405111305.283f4fea@posting.google.com...
> I would like to assign the first field to a character variable and the
> second and last one to integer variables, the third and fourth to
> float variable. The delimiter between the field is the "TAB" instead
> of spaces. So I don't know how to tell the fortran to recognize it.
> Yes, I can do this using korn shell but I need more accuracy and
> speed. I wrote a program to read it but does not work. Can anyone tell
> me where is my wrong? Thanks in advance!
Well, I would just read each input line with an '(a)' format
and then use a list-directed read on the input line with
tabs converted to spaces:
program tabtest
implicit none
character(132) line ! Big enough to hold a line of input
character(20) site ! Big enough to hold a site code
integer minute
real second
real cor_second
integer sample
open(10, file = 'tabs.dat', status = 'old')
do
read(10,'(a)',end=100) line
read(transfer(merge(achar(32),transfer(l
ine,(/'x'/)), &
transfer(line,(/'x'/))==achar(9)),line),*) &
site, minute, second, cor_second, sample
write(*,'(1x,a,1x,i0,1x,f0.3,1x,f0.3,1x,i0)') trim(site), &
minute,second,cor_second,sample
end do
100 continue
end program tabtest
My input file: (the delimiters are tabs)
ALS 23 20.000 0.000 100
GTA 23 35.000 -3.506 100
LAB 23 22.000 0.000 100
LAB002 23 58.004 -51.746 150
LAB004 23 14.004 2.870 150
LAB006 23 3.004 4.501 150
LAB008 48 21.004 -69.501 150
LAB010 23 12.004 -3.654 150
LAB012 23 21.333 2.271 150
LAB014 23 12.004 0.000 150
LAB015 23 9.004 3.577 150
LAB016 23 25.004 -3.111 150
LAB017 23 19.004 4.519 150
LAB019 23 17.004 6.207 150
LAB022 23 20.004 0.000 150
LAB023 23 16.003 13.791 150
LAB024 46 59.000 2.053 100
LAB025 46 56.000 5.930 100
Program output:
C:\LF9556\James\clf\tabtest>tabtest
ALS 23 20.000 .000 100
GTA 23 35.000 -3.506 100
LAB 23 22.000 .000 100
LAB002 23 58.004 -51.746 150
LAB004 23 14.004 2.870 150
LAB006 23 3.004 4.501 150
LAB008 48 21.004 -69.501 150
LAB010 23 12.004 -3.654 150
LAB012 23 21.333 2.271 150
LAB014 23 12.004 .000 150
LAB015 23 9.004 3.577 150
LAB016 23 25.004 -3.111 150
LAB017 23 19.004 4.519 150
LAB019 23 17.004 6.207 150
LAB022 23 20.004 .000 150
LAB023 23 16.003 13.791 150
LAB024 46 59.000 2.053 100
LAB025 46 56.000 5.930 100
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
| |
| Dr Chaos 2004-05-12, 9:09 pm |
| On 11 May 2004 14:05:11 -0700, andy <andylcx@hotmail.com> wrote:
> Hi guys there:
> I have a small question about how to read data from the ascii file
> in Fortran. The problem is that I would like to read data from one
> file like following:
>
> ALS 23 20.000 0.000 100
> GTA 23 35.000 -3.506 100
> LAB 23 22.000 0.000 100
> LAB002 23 58.004 -51.746 150
> LAB004 23 14.004 2.870 150
> LAB006 23 3.004 4.501 150
> LAB008 48 21.004 -69.501 150
> LAB010 23 12.004 -3.654 150
> LAB012 23 21.333 2.271 150
> LAB014 23 12.004 0.000 150
> LAB015 23 9.004 3.577 150
> LAB016 23 25.004 -3.111 150
> LAB017 23 19.004 4.519 150
> LAB019 23 17.004 6.207 150
> LAB022 23 20.004 0.000 150
> LAB023 23 16.003 13.791 150
> LAB024 46 59.000 2.053 100
> LAB025 46 56.000 5.930 100
> ...
> ...
> I would like to assign the first field to a character variable and the
> second and last one to integer variables, the third and fourth to
> float variable. The delimiter between the field is the "TAB" instead
> of spaces. So I don't know how to tell the fortran to recognize it.
> Yes, I can do this using korn shell but I need more accuracy and
> speed. I wrote a program to read it but does not work. Can anyone tell
> me where is my wrong? Thanks in advance!
Try implicit "*" format.
read (7,*) char6, i1,flt1,flt2,i2
it might just work fine.
| |
|
| James Van Buskirk wrote:
>
> program tabtest
> implicit none
> character(132) line ! Big enough to hold a line of input
> character(20) site ! Big enough to hold a site code
> integer minute
> real second
> real cor_second
> integer sample
>
> open(10, file = 'tabs.dat', status = 'old')
> do
> read(10,'(a)',end=100) line
> read(transfer(merge(achar(32),transfer(l
ine,(/'x'/)), &
> transfer(line,(/'x'/))==achar(9)),line),*) &
> site, minute, second, cor_second, sample
> write(*,'(1x,a,1x,i0,1x,f0.3,1x,f0.3,1x,i0)') trim(site), &
> minute,second,cor_second,sample
> end do
> 100 continue
> end program tabtest
My, oh my, is this is some sort of Svahili derivative?? OP might have
appreciated a simple Fortran solution instead...
program quicky
character*10 a
integer b,e
open(7,file='asci.dat')
do while (.not.eof(7))
read(7,*,iostat=ios) a,b,c,d,e
print*, a,b,c,d,e
enddo
end
| |
| James Giles 2004-05-12, 11:31 pm |
| bv wrote:
> James Van Buskirk wrote:
....[color=darkred]
> My, oh my, is this is some sort of Svahili derivative?? OP might have
> appreciated a simple Fortran solution instead...
Well, JVB likes line noise. But:
> do while (.not.eof(7))
The eof() function isn't Fortran.
> read(7,*,iostat=ios) a,b,c,d,e
And, of course, this is back to the original problem.
Not all Fortrans will read files containing tabs using
list directed.
--
J. Giles
| |
| Richard Maine 2004-05-13, 11:40 am |
| "James Giles" <jamesgiles@worldnet.att.net> writes:
> bv wrote:
> Well, JVB likes line noise. But:
> The eof() function isn't Fortran.
> And, of course, this is back to the original problem.
So other than not being Fortran and not being a solution, it is a
simple Fortran solution? :-)
--
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
| |
| Suzanne Voh 2004-05-15, 5:31 pm |
| James Giles wrote:
>
> The eof() function isn't Fortran.
Send your grievances and/or objections to CVF.
> Not all Fortrans will read files containing tabs using
> list directed.
Quite possibly, but who cares as long as the dominant compiler does.
| |
| James Giles 2004-05-15, 6:32 pm |
| Suzanne Voh wrote:
> James Giles wrote:
>
> Send your grievances and/or objections to CVF.
>
>
> Quite possibly, but who cares as long as the dominant compiler does.
I've never seen a dominant compiler. I suspect it'll be G95
in a few years. Right now, there are several good contenders,
CVF is only one among them. But, CVF is a defunct product.
While it's being sold by HP at the moment, they have no
plans for further development. CVF's frontend is now in
use by Intel's compiler. So, I guess you still have a compatible
development path. On the other hand, Intel may lose interest
and discontinue support because they get more interested in
some other language or product...After all, who would have
predicted Digital would go under?
Things change. If you want to sure that your code will still
work a few years down the road, I'd suggest not being too
dependent on non-standard behavior.
--
J. Giles
| |
| Richard Maine 2004-05-16, 1:31 pm |
| "James Giles" <jamesgiles@worldnet.att.net> writes:
> Suzanne Voh wrote:
Although the question was clearly rhetorical, the answer is that
quite a few people care, for multiple reasons.
[color=darkred]
> I've never seen a dominant compiler....
> Things change....
Yep. And some people learn from experience. On the other hand, there
are people like a regular poster who used to denigrate anyone who used
anything other than the one and only one acceptable compiler....until
MS stopped selling it. He then switched to DVF as the one and only
one acceptable compiler, though it had formerly been on his
unacceptable list. I'll give a pass on DVF->CVF, as it was the same
technical lineage for the compiler. As James comments, CVF is
defunct; we *KNOW* it is dissappearing, no speculation required.
Although thinhgs from CVF are going into ifort, there's clearly also
enough difference to consider them as distinct compilers. And
for the future, who knows?
I'd have thought there would be enough lesson for many people in just
that one sequence of compilers. Many of us had learned the lesson
long ago from other experiences, some very painful. I don't have a
full accounting, but man-years is the appropriate unit of measure for
the time out of my career that I've personally spent cleaning up after
people who made the mistake of writing for a particular compiler. (On
occasion, before I learned better, the person was even me).
Those kinds of experiences are what lead me into the standards
business. And even before I was formally involved in standards,
I had become an advocate of using them where appropriate.
There are things that the standard doesn't suffice and you need to
go outside of it to get the job done. I have plenty of cases of my
own, though I also know to isolate and document such things.
But the case in question isn't one of those. There is no need here -
nothing but willful ignorance, neglect, or some combination. We can
help with the ignorance problem. Normally, I prefer to avoid even
using that word, with its prejudicial connotations. When the
ignorance appears willful, helping with that needs skills other than
the technical ones that I claim some expertise in.
--
Richard Maine
email: my last name at domain
domain: sumertriangle dot net
| |
| Catherine Rees Lay 2004-05-17, 8:31 am |
| In article <40A68205.C5EE2F02@sdynamix.com>, Suzanne Voh
<svoh@sdynamix.com> writes
>James Giles wrote:
>
>Send your grievances and/or objections to CVF.
>
>
>Quite possibly, but who cares as long as the dominant compiler does.
>
>
In 5 years time when "the dominant compiler" is different, or when you
want to run on that new architecture for which it isn't available,
you do.
Catherine.
--
Catherine Rees Lay
To email me, use my first name in front of the "at".
| |
| Dr. Richard E. Hawkins 2004-05-17, 12:36 pm |
| In article <vWvpc.8985$hH.225794@bgtnsc04-news.ops.worldnet.att.net>,
James Giles <jamesgiles@worldnet.att.net> wrote:
>Suzanne Voh wrote:
>On the other hand, Intel may lose interest
>and discontinue support because they get more interested in
>some other language or product...After all, who would have
>predicted Digital would go under?
I believe that would be "most of the employees" following the
DEC=>digital conversion . . .
:)
hawk
--
Richard E. Hawkins, Asst. Prof. of Economics /"\ ASCII ribbon campaign
dochawk@psu.edu 111 Hiller (814) 375-4846 \ / against HTML mail
These opinions will not be those of X and postings.
Penn State until it pays my retainer. / \
| |
|
| James Giles wrote:
>
> I've never seen a dominant compiler.
Even if so, that doesn't imply it isn't there. You could try reasoning
with Pareto Law and quickly deduce that it must exist, unless you think
that PC domain is governed by some extraterrestrial market laws.
| |
| Dan Tex1 2004-05-17, 8:31 pm |
| >From: bv bvoh@Xsdynamix.com
>Date: 5/17/04 4:08 PM Pacific Daylight Time
>Message-id: <40A94551.F3C477A7@Xsdynamix.com>
>
>James Giles wrote:
>
>Even if so, that doesn't imply it isn't there.
hehe. It doesn't imply that it is there either. That's kind of like someone
defending their illogical and incorrect solution simply because the person who
is claiming that the solution is incorrect hasn't been able to come up with a
"better" solution.
>You could try reasoning
>with Pareto Law and quickly deduce that it must exist, unless you think
>that PC domain is governed by some extraterrestrial market laws.
Assuming momentarily that we might define the "dominant compiler" as the one
which enjoys the overwhelmingly largest market share..... ( a big assumption in
itself ).
By example, let's say:
brand A compiler has a 55% share
brand B compiler has a 25% share
brand C compiler has a 10% share
brand D compiler has a 5% share
all other brands combined have a 5% share
If brand A handles non-standard feature "x" and none of the others do, would
you feel safe using non-standard feature "x", in a large code?
Let's take it one ( LARGE ) step further. What if brand A is Microsoft???
Dan :-)
| |
| James Giles 2004-05-18, 1:31 am |
| bv wrote:
> James Giles wrote:
>
> Even if so, that doesn't imply it isn't there. You could try reasoning
> with Pareto Law and quickly deduce that it must exist, unless you think
> that PC domain is governed by some extraterrestrial market laws.
OK, assume it exists. Tell me how to determine which
compiler it is. Is it the defunct one? I don't think economics
admits of the idea that the leading product in a market
is the first to fold.
--
J. Giles
| |
|
| James Giles wrote:
>
> OK, assume it exists. Tell me how to determine which
> compiler it is. Is it the defunct one? I don't think economics
> admits of the idea that the leading product in a market
> is the first to fold.
You can't w/o seeing the numbers, however, some years back a large sw
distributor advised:
Q Which compilers should we support to cover most of the market.
A Without disclosing sales numbers (confidential), it's safe to
say that MS has the major share and you would do well to concentrate
on them alone.
It's not much of a stretch to conclude what that meant to the designated
successor. When/if CVF folds will be up to new horse owners, that
is, killing products is just a collateral damage, a blip, on a bottom
line too big to notice.
| |
| James Giles 2004-05-19, 1:31 am |
| bv wrote:
> James Giles wrote:
>
> You can't w/o seeing the numbers, however, some years back a large sw
> distributor advised:
>
> Q Which compilers should we support to cover most of the market.
> A Without disclosing sales numbers (confidential), it's safe to
> say that MS has the major share and you would do well to concentrate
> on them alone.
>
> It's not much of a stretch to conclude what that meant to the designated
> successor. When/if CVF folds will be up to new horse owners, that
> is, killing products is just a collateral damage, a blip, on a bottom
> line too big to notice.
I don't see any evidence in your response that obscure non-standard
extensions will continue to be supported. If anything, your argument
suggests that the fact that MS doesn't have an entry in the competition
is sufficient reason to abandon Fortran. I don't buy it.
--
J. Giles
|
|
|
|
|