Home > Archive > Fortran > October 2006 > Problem with reading data from files?
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 |
Problem with reading data from files?
|
|
| lghnkpg@yahoo.se 2006-09-30, 7:02 pm |
| Hi,
I'm a beginner at Fortran and I want to import files which look like
this (the numbers of rows are changing from file to file):
200609300000 0.223200546265E+003
200609300100 0.226001495361E+003
200609300200 0.137953598022E+003
200609300300 0.455557403564E+002
200609300400 0.496098976135E+002
200609300500 0.450165634155E+002
200609300600 0.411021842957E+002
200609300700 0.302365913391E+002
I have tried a lot of thing but nothing has worked.
I have try thinks like this:
index=1
open(unit=10, file='value.txt', status='old', iostat=ios)
if (ios /=0) then
write (*,*) 'Somthing is wrong with the file'
else
do
read (unit=10,fmt='(A256)',end=20) line
read (line,fmt=*) a, b
date(index) = a
value(index) = b
index=index+1
end do
20 continue
end if
Is there someone who can help me?
/Beginner
| |
| Dan Nagle 2006-09-30, 7:02 pm |
| Hello,
Where's the declaration of line?
lghnkpg@yahoo.se wrote:
> Hi,
>
> I'm a beginner at Fortran and I want to import files which look like
> this (the numbers of rows are changing from file to file):
>
> 200609300000 0.223200546265E+003
> 200609300100 0.226001495361E+003
> 200609300200 0.137953598022E+003
> 200609300300 0.455557403564E+002
> 200609300400 0.496098976135E+002
> 200609300500 0.450165634155E+002
> 200609300600 0.411021842957E+002
> 200609300700 0.302365913391E+002
>
> I have tried a lot of thing but nothing has worked.
> I have try thinks like this:
>
> index=1
> open(unit=10, file='value.txt', status='old', iostat=ios)
> if (ios /=0) then
> write (*,*) 'Somthing is wrong with the file'
> else
> do
> read (unit=10,fmt='(A256)',end=20) line
> read (line,fmt=*) a, b
> date(index) = a
> value(index) = b
> index=index+1
> end do
> 20 continue
> end if
>
> Is there someone who can help me?
>
> /Beginner
>
--
Cheers!
Dan Nagle
Purple Sage Computing Solutions, Inc.
| |
| Richard Maine 2006-09-30, 7:02 pm |
| Dan Nagle <dannagle@verizon.net> wrote:
> Where's the declaration of line?
And if that isn't it, please tell us what the problem was. Specifically.
Just "didn't work" is not sufficient data.
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
| |
| Ron Shepard 2006-09-30, 7:02 pm |
| In article <1159655707.655294.187120@m73g2000cwd.googlegroups.com>,
lghnkpg@yahoo.se wrote:
> Hi,
>
> I'm a beginner at Fortran and I want to import files which look like
> this (the numbers of rows are changing from file to file):
>
> 200609300000 0.223200546265E+003
> 200609300100 0.226001495361E+003
> 200609300200 0.137953598022E+003
> 200609300300 0.455557403564E+002
> 200609300400 0.496098976135E+002
> 200609300500 0.450165634155E+002
> 200609300600 0.411021842957E+002
> 200609300700 0.302365913391E+002
>
> I have tried a lot of thing but nothing has worked.
> I have try thinks like this:
>
> index=1
> open(unit=10, file='value.txt', status='old', iostat=ios)
> if (ios /=0) then
> write (*,*) 'Somthing is wrong with the file'
> else
> do
> read (unit=10,fmt='(A256)',end=20) line
> read (line,fmt=*) a, b
> date(index) = a
> value(index) = b
> index=index+1
> end do
> 20 continue
> end if
Your problem might be that the integer "a" (I assume it is an
integer, you don't show declarations) may not be able to hold a
value that large. If that is the problem, then you might parse the
date into fields. Also, unless you are going to use "line" for
something else, it is probably simpler just to read directly from
the file into the various values. Try something like
type date_type
integer year, month, day, time
end type date_type
type(date_type) :: date_temp
....
read (unit=10, fmt='(i4,i2,i2,i4,e20.12)') date_temp, b
I'm just guessing what are the fields, of course. Change the names
as appropriate.
$.02 -Ron Shepard
| |
| Bil Kleb 2006-09-30, 7:02 pm |
| lghnkpg@yahoo.se wrote:
> Hi,
Hi.
> I'm a beginner at Fortran and I want to import files which look like
> this (the numbers of rows are changing from file to file):
So, a http://funit.rubyforge.org Fortran unit test might look like,
$ cat << EOT > time_series_data.fun
character(len=*), parameter :: FILE = 'values.txt'
beginSetup
open(8, file=FILE)
write(8,'(a)'), '200609300000 0.223200546265E+003'
write(8,'(a)'), '200609300132 0.226001495361E+003'
close(8)
endSetup
beginTest load_time_series_data_from_file
call read_time_series( FILE )
IsEqual( 2006, ts_data(1)%date_time%year )
IsEqual( 9, ts_data(1)%date_time%month )
IsEqual( 30, ts_data(1)%date_time%day )
IsEqual( 0, ts_data(1)%date_time%hour )
IsEqual( 0, ts_data(1)%date_time%minute )
IsEqualWithin( 223.2, ts_data(1)%value, 0.1 )
IsEqual( 2006, ts_data(2)%date_time%year )
IsEqual( 9, ts_data(2)%date_time%month )
IsEqual( 30, ts_data(2)%date_time%day )
IsEqual( 1, ts_data(2)%date_time%hour )
IsEqual( 32, ts_data(2)%date_time%minute )
IsEqualWithin( 226.0, ts_data(2)%value, 0.1 )
endTest
beginTeardown
call system('rm '//FILE)
endTeardown
EOT
> Is there someone who can help me?
and the resulting code might look like,
$ cat << EOC > time_series_data.f90
module time_series_data
implicit none
integer, parameter :: MAX_POINTS = 100000 ! or use allocate
type date_time
integer :: year, month, day, hour, minute
end type date_time
type time_series
type(date_time) :: date_time
real :: value = 0.0
end type time_series
type(time_series), dimension(MAX_POINTS), save :: ts_data
contains
subroutine read_time_series( filename )
character(len=*), intent(in) :: filename
integer :: i, ios
open(10, file=filename, iostat=ios)
if (ios/=0) then
print *, 'failed to open file: >>', filename, '<<'
else
do i = 1, MAX_POINTS
read( 10, fmt='(i4,i2,i2,i2,i2,e20.12)', end=20 ) ts_data(i)
end do
print *, 'abandoned read after ', MAX_POINTS, ' points'
20 continue
end if
end subroutine read_time_series
end module time_series_data
EOC
and be check via,
$ funit time_series_data
expanding time_series_data.fun...done.
computing dependencies
locating associated source files and sorting for compilation
g95 -o TestRunner \
./time_series_data.f90 \
./time_series_data_fun.f90 \
TestRunner.f90
time_series_data test suite:
Passed 12 of 12 possible asserts comprising 1 of 1 tests.
Regards,
--
Bil Kleb
http://funit.rubyforge.org
| |
| meek@skyway.usask.ca 2006-09-30, 10:03 pm |
| In a previous article, lghnkpg@yahoo.se wrote:
>Hi,
>
>I'm a beginner at Fortran and I want to import files which look like
>this (the numbers of rows are changing from file to file):
>
>200609300000 0.223200546265E+003
>200609300100 0.226001495361E+003
>200609300200 0.137953598022E+003
>200609300300 0.455557403564E+002
>200609300400 0.496098976135E+002
>200609300500 0.450165634155E+002
>200609300600 0.411021842957E+002
>200609300700 0.302365913391E+002
>
>I have tried a lot of thing but nothing has worked.
>I have try thinks like this:
>
>index=1
>open(unit=10, file='value.txt', status='old', iostat=ios)
>if (ios /=0) then
> write (*,*) 'Somthing is wrong with the file'
>else
*do* what? - you need do i=1,1000000 e.g. or
while...do ... or (horrors) a go to
like
10 read ( .....
index=index+1
goto 10
20 ....
... or for all I know a dangling do is legal now ..?
Chris
> do
> read (unit=10,fmt='(A256)',end=20) line
> read (line,fmt=*) a, b
> date(index) = a
> value(index) = b
> index=index+1
> end do
> 20 continue
>end if
>
>Is there someone who can help me?
>
>/Beginner
>
| |
| Richard Maine 2006-09-30, 10:04 pm |
| <m @skyway.usask.ca> wrote:
> *do* what? - you need do i=1,1000000 e.g. or
> while...do ... or (horrors) a go to
No, he does not.
> ... or for all I know a dangling do is legal now ..?
Yes. Not only is it legal, it is perfect for this kind of application.
The OP has that exactly correct. Please don't lead him astray. A plain
DO is an infinite loop that is exited only when something else (usually
an exit, but possibly a goto or return) exits it. It is *FAR* better
than arbitrary numbers like the 1000000, which just asks for a hidden
bug when someday there are actually more than a million records. And
even if the 1000000 works for all cases the program is ever run for, it
is a source of confusion when reading the program; people will wonder if
there is actually some meaning to the number. I strongly recommend just
plain DO as the perfect structure here; it is what I use.
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
| |
| glen herrmannsfeldt 2006-10-01, 4:00 am |
| Richard Maine wrote:
(snip about dangling DO)
> Yes. Not only is it legal, it is perfect for this kind of application.
> The OP has that exactly correct. Please don't lead him astray. A plain
> DO is an infinite loop that is exited only when something else (usually
> an exit, but possibly a goto or return) exits it. It is *FAR* better
> than arbitrary numbers like the 1000000, which just asks for a hidden
> bug when someday there are actually more than a million records. And
> even if the 1000000 works for all cases the program is ever run for, it
> is a source of confusion when reading the program; people will wonder if
> there is actually some meaning to the number. I strongly recommend just
> plain DO as the perfect structure here; it is what I use.
In PL/I, you can have DO statements like:
DO I=1 BY 1;
or even
DO I=1 BY 0;
The BY and TO are optionally, but without both of them it is only
executed once.
-- glen
| |
| lghnkpg@yahoo.se 2006-10-01, 4:00 am |
| Hi
Thank you all for the help. I read the answer and change my program a
litle acording to your answers and know it works!
> Hi,
>
> I'm a beginner at Fortran and I want to import files which look like
> this (the numbers of rows are changing from file to file):
>
> 200609300000 0.223200546265E+003
> 200609300100 0.226001495361E+003
> 200609300200 0.137953598022E+003
> 200609300300 0.455557403564E+002
> 200609300400 0.496098976135E+002
> 200609300500 0.450165634155E+002
> 200609300600 0.411021842957E+002
> 200609300700 0.302365913391E+002
>
> I have tried a lot of thing but nothing has worked.
> I have try thinks like this:
>
> index=1
> open(unit=10, file='value.txt', status='old', iostat=ios)
> if (ios /=0) then
> write (*,*) 'Somthing is wrong with the file'
> else
> do
> read (unit=10,fmt='(A256)',end=20) line
> read (line,fmt=*) a, b
> date(index) = a
> value(index) = b
> index=index+1
> end do
> 20 continue
> end if
>
> Is there someone who can help me?
>
> /Beginner
| |
| Bil Kleb 2006-10-01, 8:01 am |
| Richard Maine wrote:
> <m @skyway.usask.ca> wrote:
>
>
> No, he does not.
>
>
> Yes. Not only is it legal, it is perfect for this kind of application.
> The OP has that exactly correct. Please don't lead him astray.
How would you allocate date and value, e.g.,
date(index) = a
value(index) = b
if you don't take the path of explicit dimensions?
Blocked reallocations?
Thanks,
--
Bil Kleb
http://c2.com/cgi/wiki?BilKleb
| |
| Richard Maine 2006-10-01, 7:03 pm |
| Bil Kleb <Bil.Kleb@NASA.gov> wrote:
> Richard Maine wrote:
>
> How would you allocate date and value, e.g.,
>
> date(index) = a
> value(index) = b
>
> if you don't take the path of explicit dimensions?
>
> Blocked reallocations?
There are all kinds of approaches to that. I don't have even close to
enough information to make a recommendation. (Though the fact that the
OP is new to the language suggests that it better be something pretty
simple, which likely rules out most of the options.) Blocked
reallocations is one option; I usually like the scheme of doubling the
size each time when I do that. Building a temporary linked list is
another. Not using an array at all is another. Or yes, using a fixed
size array and checking for hitting the limit is sometimes an option.
(And then there is the option of using a fixed size array, but not
bothering to check - an option that I see used far too often,
particularly when helping people dbug their code. :-(). I've done all of
the above at one time or other (though the times when I did the
unchecked fixed dimension were long ago, except in the most trivial of
throwaway code.)
But I don't see that as particularly correlated with the matter I was
addressing, which is the use of infinite DO loops. Yes, one can use a
finite DO loop as a form of limit checking of fixxed-size arrays. THat's
often handy in fact. But I didn't see any element of that in what I was
replying to. There was no suggestion that the DO loop go to size(date),
or anything comparable. All I saw was the "pick a large number" scheme,
which indeed I had been known to use myself in days gone by, but I would
never consider today. (I had stopped that practice and dropped back to
using loops built with goto sometime in my f77 days.)
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
| |
| Bil Kleb 2006-10-02, 8:03 am |
| Richard Maine wrote:
>
> (Though the fact that the
> OP is new to the language suggests that it better be something pretty
> simple, which likely rules out most of the options.)
Which is why I went straight to the explicit fixed-size
storage, but I found it rather embarrassing that I couldn't
figure out something better that was still simple. I am curious
to see another solution. I freely admit my Fortran is rusty.
With a higher-level language (e.g., Ruby), I might write,
Data = Struct.new(:year, :month, :day, :hour, :minute, :value)
time_series = Array.new
File.foreach('values.txt') do |line|
time_series << Data.new( *line.scan(/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)\s+(.*)/) )
end
(with an accompanying unit test of course).
Regards,
--
Bil Kleb
http://fun3d.larc.nasa.gov
| |
| meek@skyway.usask.ca 2006-10-02, 8:03 am |
| In a previous article, nospam@see.signature (Richard Maine) wrote:
><m @skyway.usask.ca> wrote:
>
>
>No, he does not.
>
>
>Yes. Not only is it legal, it is perfect for this kind of application.
>The OP has that exactly correct. Please don't lead him astray. A plain
>DO is an infinite loop that is exited only when something else (usually
>an exit, but possibly a goto or return) exits it. It is *FAR* better
>than arbitrary numbers like the 1000000, which just asks for a hidden
I agree- the dangling do is best. I would have used a goto
rather than the 100000 - but now I will check out the DD.
Chris
<snip>
|
|
|
|
|