replica nfl jerseysreplica nfl jerseyssoccer jerseyreplica nfl jerseys forums.silverfrost.com :: View topic - Problem reading last character
forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Problem reading last character

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
simon



Joined: 05 Jul 2006
Posts: 299

PostPosted: Wed Jun 24, 2009 10:03 am    Post subject: Problem reading last character Reply with quote

This simple program will not read the last character of the string.
The second output line generates a blank.
Code:

PROGRAM p
  IMPLICIT NONE
  CHARACTER(LEN=26) :: c1
  CHARACTER(LEN= 1) :: c2
!
  c1='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  READ (UNIT=c1(26:),FMT=*) c2
  WRITE (UNIT=*,FMT=*) c1(26:)
  WRITE (UNIT=*,FMT=*) c2
  READ (UNIT=c1(25:),FMT=*) c2
  WRITE (UNIT=*,FMT=*) c1(25:)
  WRITE (UNIT=*,FMT=*) c2
END PROGRAM p
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2402
Location: Yateley, Hants, UK

PostPosted: Wed Jun 24, 2009 11:44 am    Post subject: Reply with quote

Simon, you are trying to read a single character with a * format, and that can't pick up the quote marks. Here's an effort to get them in place.

Eddie


Code:
PROGRAM p
  IMPLICIT NONE
  CHARACTER(LEN=26) :: c1
  CHARACTER(LEN= 3) :: c2
!
  c1='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  READ (UNIT=c1(1:1)//c1(26:),FMT=*) c2
  WRITE (UNIT=*,FMT=*) c1(26:)
  WRITE (UNIT=*,FMT=*) c2
  READ (UNIT=c1(25:),FMT=*) c2
  WRITE (UNIT=*,FMT=*) c1(25:)
  WRITE (UNIT=*,FMT=*) c2
END PROGRAM p
Back to top
View user's profile Send private message
simon



Joined: 05 Jul 2006
Posts: 299

PostPosted: Wed Jun 24, 2009 7:01 pm    Post subject: Reply with quote

Thanks for the reply Eddie. I get 'A ' as the second output so the Z is still missing. Perhaps I should give a little bit more background to indicate why this problem arises.

Let me change the program to the following:

Code:
PROGRAM p
  IMPLICIT NONE
  CHARACTER(LEN=26) :: c1
  CHARACTER(LEN= 3) :: c2
!
  c1='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  READ (UNIT=c1(26:),FMT=*) c2
  WRITE (UNIT=*,FMT=*) c1(26:)
  WRITE (UNIT=*,FMT=*) c2
  READ (UNIT=c1(25:),FMT=*) c2
  WRITE (UNIT=*,FMT=*) c1(25:)
  WRITE (UNIT=*,FMT=*) c2
END PROGRAM p


The only difference from the original is that c2 is length 3 instead of 1. c1 typically is a line containing a string of information marked by tags. For example, c1 may look like the following:

'NAME=Simon, SEX=M, OCCUPATION=scientist'

I search for the keywords written in bold and then read the corresponding values. The keywords are not necessarily always present, and can be in any order, and the length of the value string is not fixed (for example, SEX could be 'Male' or 'M').

In the example above, I can read all the values OK, but if the order is reversed:

'NAME=Simon, OCCUPATION=scientist, SEX=M'

then I may fail to read M if there are no trailing blanks.

I have to use READ with FMT=* rather than FMT='(A)' because otherwise when the values are in the original order I would read past the comma separators, and would then have to check to delete any extraneous text.

It is not too difficult to think of work-arounds, but it seems circuitous to have to be checking whether one is left trying to read only the last character.


Last edited by simon on Mon Jul 06, 2009 1:28 pm; edited 1 time in total
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2615
Location: Sydney

PostPosted: Thu Jun 25, 2009 4:43 am    Post subject: Reply with quote

I'd go back to (A) or not use read statements at all.

Alteranatively why not parse the line testing for "," and "=", keeping track of each couple and where the ,name and =value start.

Code:

PROGRAM p
  IMPLICIT NONE
  CHARACTER(LEN=26) :: c1
  CHARACTER(LEN= 1) :: c2
!
  c1='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
!
! this works with (a)
  READ (UNIT=c1(26:),FMT=11) c2
  WRITE (UNIT=*,FMT=11) c1(26:)
  WRITE (UNIT=*,FMT=11) c2
!
  READ (UNIT=c1(25:),FMT=11) c2
  WRITE (UNIT=*,FMT=11) c1(25:)
  WRITE (UNIT=*,FMT=11) c2
11 format (a)
!
! or better still, use
  c2 = c1(26:)
  WRITE (UNIT=*,FMT=*) c1(26:)
  WRITE (UNIT=*,FMT=*) c2
!
  c2 = c1(25:)
  WRITE (UNIT=*,FMT=*) c1(25:)
  WRITE (UNIT=*,FMT=*) c2
!

END PROGRAM p
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2402
Location: Yateley, Hants, UK

PostPosted: Thu Jun 25, 2009 6:01 pm    Post subject: Reply with quote

Simon,

I only did the first one, and without too much care!

Isn't this a good example of where one might consider using NAMELIST? I'm not a big fan of NAMELIST, but if your data is in the form you indicate, NAMELIST takes care of all the decyphering. Presumably each line has the same format because each line is generated by some other software.

If the data is generated by humans (and the keywords may be missing or mispelled) then you are in a whole different, and potentially more complex, ballgame.

NAMELIST is definitely a standard feature in later marks of Fortran, and is fully supported in FTN95.

Eddie
Back to top
View user's profile Send private message
simon



Joined: 05 Jul 2006
Posts: 299

PostPosted: Fri Jul 03, 2009 10:55 am    Post subject: Reply with quote

I found a simple solution to this problem: when reading the string, simply append a blank space to the end, as follows:

Code:
PROGRAM p
  IMPLICIT NONE
  CHARACTER(LEN=26) :: c1
  CHARACTER(LEN= 3) :: c2
!
  c1='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  READ (UNIT=c1(26:)//' ',FMT=*) c2
  WRITE (UNIT=*,FMT=*) c1(26:)
  WRITE (UNIT=*,FMT=*) c2
  READ (UNIT=c1(25:)//' ',FMT=*) c2
  WRITE (UNIT=*,FMT=*) c1(25:)
  WRITE (UNIT=*,FMT=*) c2
END PROGRAM p
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2615
Location: Sydney

PostPosted: Fri Jul 03, 2009 1:03 pm    Post subject: Reply with quote

Simon,

If you want a simple solution, why use a read at all ?

Doesn't " c2 = c1(26:) " do the same thing ?

John
Back to top
View user's profile Send private message
simon



Joined: 05 Jul 2006
Posts: 299

PostPosted: Mon Jul 06, 2009 1:23 pm    Post subject: Reply with quote

John,

Certainly, but only if one knew a priori that there were no trailing characters. The problem I originally raised only occurred because I was being too lazy to check whether I was at or near the end of the string. I could easily have included a LEN_TRIM somewhere, and checked how many characters were left, but that seemed a bit pedantic. Having the trailing blank seems to have solved all the problems in my specific context, for now. Eddie's suggestion about NAMELIST was a good one, and would work in over 90% of my cases, but there are occasional fields generated or modified by hand that I'm having to account for.

Simon
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2615
Location: Sydney

PostPosted: Mon Jul 06, 2009 1:33 pm    Post subject: Reply with quote

Simon,

I would expect that the problem relates to the interpretation of fmt=*
If you used fmt='(a)' the result may have been different.
I have written my free format interpreter without the use of formatted read. It is an easy solution.

The effective use of NAMELIST is something I have never managed to learn.

John
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group