Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion Writing an 'online calculator' in fortran
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Richard Maine  
View profile  
 More options Sep 17 2009, 12:41 pm
Newsgroups: comp.lang.fortran
From: nos...@see.signature (Richard Maine)
Date: Thu, 17 Sep 2009 09:41:00 -0700
Subject: Re: Writing an 'online calculator' in fortran

Jason Blevins <jrble...@sdf.lonestar.org> wrote:
> On Sep 17, 2009, at  9:46 AM, us...@example.net wrote:
> > A Fortran version of strtok could be useful for breaking up the
> > strings that come from the cgi input. ( stuff looks like
> > &val1=abcd&val2=1234 )

> Here is a strtok implementation, courtesy of John Urban:

> http://fortranwiki.org/fortran/show/strtok

Here's my equivalent, which I've used for nearly 2 decades, as you can
see from the date. This doesn't try to mimic the C strtok (and doesn't
have its limitations either). It is in a much more native Fortran style.

It is a little more complicated than some because it does some things
that I regularly find useful. For example, it can tell the caller what
trailing delimitter it found. This can be useful, for example, to
distinguish between

  somefield, someotherfield

versus

  somefield=somevalue, someotherfield

Also, I have a bit of special handling for blanks. All the usage
information is in the argument comments. Note that most of the arguments
are optional.

This is normally in a module. It does reference one other routine of
mine, but I presume the function of error_halt should be obvious.

  subroutine find_field (string, field, position, delims, delim, found)

    !-- Find a delimitted field in a string.
    !-- 15 Nov 90, Richard Maine.

    !-------------------- interface.
    character*(*), intent(in) :: string   !-- The string input.
    character*(*), intent(out) :: field
         !-- The returned field.  Blank if no field found.
    integer, optional, intent(inout) :: position
         !-- On entry, the starting position for searching for the
field.
         !-- Default is 1 if the argument is not present.
         !-- On exit, the starting position of the next field or
         !-- len(string)+1 if there is no following field.
    character*(*), optional, intent(in) :: delims
         !-- String containing the characters to be accepted as
delimitters.
         !-- If this includes a blank character, then leading blanks are
         !-- removed from the returned field and the end delimitter may
         !-- optionally be preceeded by blanks.  If this argument is
         !-- not present, the default delimitter set is a blank.
    character*(*), optional, intent(out) :: delim
         !-- Returns the actual delimitter that terminated the field.
         !-- Returns char(0) if the field was terminated by the end of
         !-- the string or if no field was found.
         !-- If blank is in delimitters and the field was terminated
         !-- by one or more blanks, followed by a non-blank delimitter,
         !-- the non-blank delimitter is returned.
    logical, optional, intent(out) :: found
         !-- True if a field was found.

    !-------------------- local.
    character :: delimitter*1
    integer :: pos, field_start, field_end, i
    logical :: trim_blanks

    !-------------------- executable code.

    field = ''
    delimitter = char(0)
    pos = 1
    if (present(found)) found = .false.
    if (present(position)) pos = position
    if (pos > len(string)) goto 9000
    if (pos < 1) call error_halt('Illegal position in find_field')

    !-- Skip leading blanks if blank is a delimitter.
    field_start = pos
    trim_blanks = .true.
    if (present(delims)) trim_blanks = index(delims,' ') /= 0
    if (trim_blanks) then
      i = verify(string(pos:),' ')
      if (i == 0) then
        pos = len(string) + 1
        goto 9000
      end if
      field_start = pos + i - 1
    end if
    if (present(found)) found = .true.

    !-- Find the end of the field.
    if (present(delims)) then
      i = scan(string(field_start:), delims)
    else
      i = scan(string(field_start:), ' ')
    end if
    if (i == 0) then
      field_end = len(string)
      delimitter = char(0)
      pos = field_end + 1
    else
      field_end = field_start + i - 2
      delimitter = string(field_end+1:field_end+1)
      pos = field_end + 2
    end if

    !-- Return the field.
    field = string(field_start:field_end)

    !-- Skip trailing blanks if blank is a delimitter.
    if (trim_blanks) then
      i = verify(string(field_end+1:), ' ')
      if (i == 0) then
        pos = len(string) + 1
        goto 9000
      end if
      pos = field_end + i

      !-- If the first non-blank character is a delimitter,
      !-- skip blanks after it.
      i = 0
      if (present(delims)) i = index(delims, string(pos:pos))
      if (i /= 0) then
        delimitter = string(pos:pos)
        pos = pos + 1
        i = verify(string(pos:), ' ')
        if (i == 0) then
          pos = len(string) + 1
        else
          pos = pos + i - 1
        end if
      end if
    end if

    !---------- Normal exit.
    9000 continue
    if (present(delim)) delim = delimitter
    if (present(position)) position = pos
    return
  end subroutine find_field

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


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.