Home > Archive > Fortran > August 2005 > Count Items function
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 |
Count Items function
|
|
| David Frank 2005-08-17, 4:07 am |
| "sly one" asked in his original topic "Number of columns" topic
" Given an input text file of space separated number data (of same type
to make it simple), can you think of an elegant way to extract number
of columns in a given row? (using pure Fortran, of course)
- each EOL starts a new row
- every column is separated by at least one space -- can be more"
slyi.
This topic having "tree'ed out" is now continued here with a goal to develop
a FAST/LEGIBLE/BRIEF
Count_Items function.
Note: having a Count_Items function solves the problem of processing file
records using list input.
For my function see: http://home.earthlink.net/~davegemini/strings.f90
A new topic also serves to break the cross-posting with comp.lang.pl1 that
began in the previous topic
| |
|
|
| Arjen Markus 2005-08-17, 4:07 am |
| Your page did not show, so I can not check your solution.
But if there is a known limit on the length of the lines in the file,
code
like the following can be used:
character(len=limitlen) :: line
character(len=1) :: dummy
read(10, '(a)' ) line
noitems = 1
do
read( line, *, iostat=ierr ) ( dummy , i=1,noitems )
if ( ierr .eq. 0 ) then
noitems = noitems + 1
else
noitems = noitems - 1
exit
endif
enddo
Is that elegant enough?
Regards,
Arjen
| |
| David Frank 2005-08-17, 9:14 am |
|
"Arjen Markus" <arjen.markus@wldelft.nl> wrote in message
news:1124269700.733254.318160@z14g2000cwz.googlegroups.com...
> Your page did not show, so I can not check your solution.
>
A corrected link was posted prior to your reply.
> But if there is a known limit on the length of the lines in the file,
> code
> like the following can be used:
>
> character(len=limitlen) :: line
> character(len=1) :: dummy
>
> read(10, '(a)' ) line
> noitems = 1
> do
> read( line, *, iostat=ierr ) ( dummy , i=1,noitems )
> if ( ierr .eq. 0 ) then
> noitems = noitems + 1
> else
> noitems = noitems - 1
> exit
> endif
> enddo
>
> Is that elegant enough?
>
> Regards,
>
> Arjen
>
I dont think so by a LONG shot, however I did test your routine (below)
which does work.
include "strings.f90"
! -----------------------
program number_decode
use string_functions
implicit none
integer :: i, n, v(100) ! len(line)/2 = possible values/record
integer :: ierr
character(200) :: line
character :: dummy
open (1,file='test.txt') ! create a test file
write (1,'(a)') '11 222 0 333 44444'
write (1,'(a)') ' 55 666 777, 888888 -999'
write (1,*) ! blank line
rewind (1)
do ! dave f. solution
read (1,'(a)',end=101) line
n = count_items(line)
read (line,*) v(1:n)
write (*,91) v(1:n)
end do
101 rewind(1)
do ! arjen markus solution
read(1,'(a)',end=102) line
n = 1
do
read(line, *, iostat=ierr ) ( dummy , i=1,n)
if ( ierr .eq. 0 ) then
n = n + 1
else
n = n - 1
exit
endif
enddo
read (line,*) v(1:n)
write (*,91) v(1:n)
end do
102 stop
91 format (999(i0,1x))
end program
! outputs:
! 11 222 0 333 44444
! 55 666 777 888888 -999
! <blank line>
! 11 222 0 333 44444
! 55 666 777 888888 -999
! <blank line>
| |
| Arjen Markus 2005-08-17, 9:14 am |
| Interesting solution indeed:
INTEGER FUNCTION Count_Items(s) ! in string that are blank separated
CHARACTER(*) :: s
INTEGER :: i
Count_Items = COUNT([LEN_TRIM(s) > 0,(s(i:i)/=' '.AND.s(i+1:i+1)==' ',
i=1,LEN_TRIM(s)-1)])
END FUNCTION Count_Items
My solution can lead to a different result if:
- There are commas in the string
- Substrings are surrounded by "..."
Regards,
Arjen
| |
| David Frank 2005-08-17, 9:14 am |
|
"Rich Townsend" <rhdt@barVOIDtol.udel.edu> wrote in message
news:ddt2sc$rcu$2@scrotar.nss.udel.edu...
>
>
> No, the only F95 solution is to use ISO_VARYING_STRING or some similar,
> home-grown capability.
>
> cheers,
>
> Rich
Nonsense, there is no reason to say that a adequate length declaration cant
be satisfactory used in ANY
DP environment. I have noticed no significant slowdown between using trim'ed
string declarations
character(10000) :: bigline
character(100) :: normal_dp_line
However my http://home.earthlink.net/~dave_gemini/numdec.f90
solution #3 does not even have a line declaration.
| |
| Rich Townsend 2005-08-17, 9:15 am |
| David Frank wrote:
> "Rich Townsend" <rhdt@barVOIDtol.udel.edu> wrote in message
> news:ddt2sc$rcu$2@scrotar.nss.udel.edu...
>
>
>
> Nonsense, there is no reason to say that a adequate length declaration cant
> be satisfactory used in ANY
> DP environment. I have noticed no significant slowdown between using trim'ed
> string declarations
> character(10000) :: bigline
> character(100) :: normal_dp_line
This breaks for lines greater than 10000 characters long. Try again
>
> However my http://home.earthlink.net/~dave_gemini/numdec.f90
>
> solution #3 does not even have a line declaration.
>
>
No, it uses an OPEN(..., FORM='binary'), which is not standard F95 (see
the explicit statements about F95 above; I don't care what can be done
in F2003, I am talking about F95, and so are you).
Furthermore, your code assumes lines terminate with CR, which is
non-portable.
Keep trying, David!
cheers,
Rich
| |
| David Frank 2005-08-17, 9:15 am |
| include 'iso.f90'
! ---------------------
program demo_varying_string
use iso_varying_string
type (varying_string) :: line
character(10000) :: bigline = 'bigline'
open (1,file='test.txt')
write (1,'(a)') bigline
rewind (1)
read (1,'(a)') bigline
write (*,*) bigline(1:8) ! outputs "bigline"
rewind (1)
pls supply the code to read bigline -> line and then output bigline(1:8)
end program
| |
| Rich Townsend 2005-08-17, 5:04 pm |
| David Frank wrote:
> include 'iso.f90'
> ! ---------------------
> program demo_varying_string
> use iso_varying_string
> type (varying_string) :: line
> character(10000) :: bigline = 'bigline'
>
> open (1,file='test.txt')
> write (1,'(a)') bigline
> rewind (1)
>
> read (1,'(a)') bigline
> write (*,*) bigline(1:8) ! outputs "bigline"
>
> rewind (1)
>
> pls supply the code to read bigline -> line and then output bigline(1:8)
>
> end program
>
>
Try:
call get(1, line)
write (*,*) CHAR(EXTRACT(line, 1, 8))
I'm interested to see where you're going with this.
cheers,
Rich
| |
| David Frank 2005-08-18, 4:03 am |
|
"Rich Townsend" <rhdt@barVOIDtol.udel.edu> wrote in message
news:ddvml5$lgf$1@scrotar.nss.udel.edu...
> David Frank wrote:
>
> Try:
>
> call get(1, line)
> write (*,*) CHAR(EXTRACT(line, 1, 8))
>
> I'm interested to see where you're going with this.
>
> cheers,
>
> Rich
>
For starters call get(1,line) isnt equivalent to
read(1,'(a)',end=101) line
how do you gracefully exit file input from a do loop at EOF?
| |
| David Frank 2005-08-18, 4:04 am |
|
"Rich Townsend" <rhdt@barVOIDtol.udel.edu> wrote in message
news:ddvml5$lgf$1@scrotar.nss.udel.edu...
> David Frank wrote:
>
> Try:
>
> call get(1, line)
> write (*,*) CHAR(EXTRACT(line, 1, 8))
>
> I'm interested to see where you're going with this.
>
> cheers,
>
> Rich
>
Apparently not far, supplying your 2 statements in my test program causes
CVF to barf with a internal error.
Do you dispute the fact that any applications developed now using your
varying strings will not only be
obsolete, but will likely have to be re-programmed about a year from now?
You are doing a great dis-service to those here gullible enuf to buy into
your varying string touting.
| |
| Rich Townsend 2005-08-18, 5:59 pm |
| David Frank wrote:
> "Rich Townsend" <rhdt@barVOIDtol.udel.edu> wrote in message
> news:ddvml5$lgf$1@scrotar.nss.udel.edu...
>
>
>
> Apparently not far, supplying your 2 statements in my test program causes
> CVF to barf with a internal error.
That's because you are using an obsolte compiler. My code is valid
Fortran; your compiler is broken.
>
> Do you dispute the fact that any applications developed now using your
> varying strings will not only be
> obsolete, but will likely have to be re-programmed about a year from now?
What, like netlib had to be reprogrammed when F90 compilers came out?
What a ridiculous claim you are making!
> You are doing a great dis-service to those here gullible enuf to buy into
> your varying string touting.
How so? By showing you up as a charlatan and a fool?
| |
| Rich Townsend 2005-08-18, 5:59 pm |
| David Frank wrote:
> "Rich Townsend" <rhdt@barVOIDtol.udel.edu> wrote in message
> news:ddvml5$lgf$1@scrotar.nss.udel.edu...
>
>
>
>
> For starters call get(1,line) isnt equivalent to
> read(1,'(a)',end=101) line
> how do you gracefully exit file input from a do loop at EOF?
You use the iostat optional argument to GET(), and test for negative values:
call GET(1, line, iostat)
if(iostat < 0) goto 101
Honestly, David, I suggest you go and read the standard before you try
to move the goal posts once again. It's not that there aren't flaws in
ISO_VARYING_STRING. But in your ignorance of the standard (as,
apparently, also with PL/1's bifs), your arrows keep missing their
intended target.
cheers,
Rich
| |
| David Frank 2005-08-18, 5:59 pm |
|
"Rich Townsend" <rhdt@barVOIDtol.udel.edu> wrote in message
news:de1rt3$b6m$1@scrotar.nss.udel.edu...
> David Frank wrote:
>
> What, like netlib had to be reprogrammed when F90 compilers came out? What
> a ridiculous claim you are making!
>
>
> How so? By showing you up as a charlatan and a fool?
In another topic I complained about not being able to read/write your
strings, to which you acknowledged,
>You're wanting varying strings to behave in exactly the same way as
>character. Well, they don't, and there is no way they ever can
You of course were talking about YOUR varying strings, THE STANDARD's
varying strings
support READ/WRITE using them, and I stand by my statement that those
gullible enuf to buy into using
your version are going to have toss them out and re-program at some future
date.
| |
| Rich Townsend 2005-08-18, 5:59 pm |
| David Frank wrote:
> "Rich Townsend" <rhdt@barVOIDtol.udel.edu> wrote in message
> news:de1rt3$b6m$1@scrotar.nss.udel.edu...
>
>
>
>
>
> In another topic I complained about not being able to read/write your
> strings, to which you acknowledged,
>
>
>
>
> You of course were talking about YOUR varying strings, THE STANDARD's
> varying strings
> support READ/WRITE using them, and I stand by my statement that those
> gullible enuf to buy into using
> your version are going to have toss them out and re-program at some future
> date.
By 'varying strings', I've been talking about VARYING_STRING derived
types, as defined in ISO/IEC 1539-2:2000 "Information technology -
Programming languages - Fortran - Part 2: Varying length character
strings". As others have already pointed out, this is the most recent
revision to part 2 of the Fortran standard.
You might now claim that the term 'varying string' refers to the
allocatable-length character variables introduced in F2003. However,
I've just done a text search through the F2003 standard document (more
precisely, the most recent draft, which I believe is almost identical to
the ratified standard), looking for the the phrase 'varying string'.
Zero matches. Zilch. Nada.
I think even a 10 year old child would therefore conclude that the
phrase 'varying string', in association with the word 'standard', refers
to the VARYING_STRING derived types, and not to allocatable-length
character variables. That's certainly my interpretation. You might claim
otherwise, but I don't really care.
cheers,
Rich
|
|
|
|
|