Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Internal Read and Write using variable format statement in gfortran 2

Status
Not open for further replies.

mtamimi

Technical User
Dec 27, 2012
9
US
Hi
I have used FPS 4.0 for along time. I ran into some problems in the program I am writing for my research and just decided to switch to gfortran because its more recent and I can use a newer debugger. I found Code::Block IDE that utilize gfortran as compiler and GDB as a debugger. It was easier to get to writing programs and compiling them than NetBeans and Eclipse. To use what I wrote before under FPS 4.0 I had to change few areas of my code and I seem to get it compiled fine.
Now I am working through run time problems. The first one was dealing with data conversions.
I want to be able to convert from integer to string. I know that this is only done via internal write. I could do this using fixed format statement. I am running into a problem when I use a variable format statement. I am not sure why. Any idea’s????
The following is the code I wrote for that function
Code:
program conversiontest
    implicit none
character(Len=20)   :: Int2Str, TmpStr,Int2StrwFrmt

    TmpStr = adjustl("I") // adjustl(Int2Str(5))
    print *, TmpStr

    TmpStr = adjustl("I") // adjustl(Int2Str(50))
    print *, TmpStr

    TmpStr = adjustl("I") // adjustl(Int2Str(65))
    print *, TmpStr

    TmpStr = Int2StrwFrmt(5,"I3")
    print *, TmpStr

end program conversiontest

Character(Len=20)  Function Int2Str(InInt)

implicit none

integer :: InInt

        Write(Int2Str,'(i10)') InInt

end Function Int2Str

Character(Len=20)  Function Int2StrwFrmt(InInt,FormatString)

implicit none

integer             :: InInt
Character(Len=20)   :: TempString
character*(*)       :: FormatString

        TempString = Char(34) // char(40) //  &
                   & Adjustl(FormatString) // &
                   & Char(41) // char(34)
        write(*,*) TempString, len_trim(TempString)

        Write(Int2StrwFrmt,TempString(:len_trim(TempString)) ) InInt

end Function Int2StrwFrmt

the first function works fine - fixed format statement.
I wanted to be able touse variable format statement - funtion two; to be able to generate numbers like 0001 and so on. I get the following error when I run it:
Fortran runtime error: Missing initial left parenthesis in format
"(I3)"
^
any idea's???

mtamimi@netzero.net
 
You don't need the quotes.
Code:
Character(Len=20)  Function Int2StrwFrmt(InInt,FormatString)

implicit none

integer             :: InInt
Character(Len=20)   :: TempString
character*(*)       :: FormatString

        TempString = '('// Adjustl(FormatString) // ')' 
        write(*,*) TempString, len_trim(TempString)

        Write(Int2StrwFrmt,TempString(:len_trim(TempString)) ) InInt

end Function Int2StrwFrmt
If you want leading zeros, here is a simple trick. Just make sure the numbers are positive otherwise you will get strange results
Code:
character(len=20) function LeadingZero(in_int, in_digits)
implicit none
integer, intent(in):: in_int
integer, intent(in):: in_digits
character(len=20)  :: tempstring

!                     ,-- Maximum of 7 leading zeros
!                     |             ,-- Add this to get leading zeros
write (tempstring, '(I8)') in_int + 10000000
!                  ,----- Max # of digits + 2
!                  |             ,-- Max # of digits + 1
I2Str = tempstring(9 - in_digits:8)
end function LeadingZero
 
Hi
Thanks that was simple enough. it works fine when removing the quotes.
As far as having leading zeros: I was able to use for example "I8.8" and it displayed the leading zero's. Would that work her???
 
Some comments:

adjustl(string) removes leading blanks but adds them to the end. If string has 20 characters, the first three blanks, then 5 non-blanks and 12 blanks adjustl(string) will give a 20 character string with the 5 non-blanks in the beginning and 15 trailing blanks. So the statement

TempString = '('// Adjustl(FormatString) // ')'

might produce a string like
Code:
(I3   )
If TempString and FormatString are of the same size however, then the closing bracket will be lost. What you need would be

TempString = '('// trim (adjustl (FormatString)) // ')'

which gives left-adjusted
Code:
(I3)
with any number of trailing blanks (depending on size of TempString).

In my Compaq-compiler - and I guess it is standard fortran - Iw.m forces the integer output of m digits, filling up the field with leading zeros if necessary.

In my mind however, you do not need a variable format.

Code:
Program ConversionTest
implicit none
character*20 Int2Str, String
integer int, num

int = 1234567
Int2Str = '00000000000000000000'         ! assumed you want all leading characters to be zeros
write (String, '(i20)') int              ! convert int to string
num = 20 - len_trim (adjustl (String))   ! find out how many leading zeros are needed
String = adjustr(String)                 ! make it rightbound
Int2Str = Int2Str (1 : num) // String (num + 1 : 20)
write (*,*) Int2Str
stop
end

This will print

00000000000001234567

Norbert


The optimist believes we live in the best of all possible worlds - the pessimist fears this might be true.
 
Yes, I'd forgotten about I8.8. I think that worked in F66 as well.

I knew I'd done it before but just couldn't remember how. Thanks for the reminder.
 
Hello
Thanks for the help. I wrote the following two function that work fine for what I wanted to do - so far. I would like to share them just in case someone is looking for such functions:
Code:
program conversiontest
    implicit none
character(Len=20)   :: Int2Str, TmpStr,Int2StrwFrmt

    TmpStr = adjustl("I") // adjustl(Int2Str(5))
    print *, TmpStr

    TmpStr = adjustl("I") // adjustl(Int2Str(50))
    print *, TmpStr

    TmpStr = adjustl("I") // adjustl(Int2Str(65))
    print *, TmpStr

    TmpStr = Int2StrwFrmt(5,"I3")
    print *, TmpStr

    TmpStr = Int2StrwFrmt(5,"I6.6")
    print *, TmpStr

    TmpStr = Int2StrwFrmt(5897,"I15.15")
    print *, TmpStr

end program conversiontest

Character(Len=20)  Function Int2Str(InInt)

implicit none

integer :: InInt

        Write(Int2Str,'(i10)') InInt

end Function Int2Str
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Character(Len=20)  Function Int2StrwFrmt(InInt,FormatString)

implicit none

Integer             :: InInt
Character(Len=20)   :: TempString
Character*(*)   :: FormatString

        TempString = char(40) //  &
                   & Adjustl(FormatString) // &
                   & Char(41)
        write(*,*) TempString, len_trim(TempString)

        Write(Int2StrwFrmt,TempString(:len_trim(TempString)) ) InInt

End Function Int2StrwFrmt
!XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Thanks alot for all the help.
mtamimi@netzero.net
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top