 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
simon
Joined: 05 Jul 2006 Posts: 299
|
Posted: Wed Jun 24, 2009 10:03 am Post subject: Problem reading last character |
|
|
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 |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Wed Jun 24, 2009 11:44 am Post subject: |
|
|
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 |
|
 |
simon
Joined: 05 Jul 2006 Posts: 299
|
Posted: Wed Jun 24, 2009 7:01 pm Post subject: |
|
|
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 |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Thu Jun 25, 2009 4:43 am Post subject: |
|
|
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 |
|
 |
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2402 Location: Yateley, Hants, UK
|
Posted: Thu Jun 25, 2009 6:01 pm Post subject: |
|
|
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 |
|
 |
simon
Joined: 05 Jul 2006 Posts: 299
|
Posted: Fri Jul 03, 2009 10:55 am Post subject: |
|
|
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 |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Fri Jul 03, 2009 1:03 pm Post subject: |
|
|
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 |
|
 |
simon
Joined: 05 Jul 2006 Posts: 299
|
Posted: Mon Jul 06, 2009 1:23 pm Post subject: |
|
|
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 |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Mon Jul 06, 2009 1:33 pm Post subject: |
|
|
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 |
|
 |
|
|
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
|