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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

variable string length function

Status
Not open for further replies.

augh

Programmer
Dec 21, 2008
5
IT
Here is another maybe-trivial--problem.

I cannot figure out how to write a character function that returns a variable-length string just like the intrinsic [tt]trim[/tt] does.

In the example below, the [tt]len[/tt] applied to [tt]trim[/tt] returns
the length of the trimmed string.

Code:
character(len=100) :: qaz='qwerty'

print*,len(qaz)
print*,len(trim(qaz))

How can I write my own [tt]mytrim[/tt]?
How does fortran manage the length of strings?

 
I don't know how to write trim() in Fortran but here is an example of a string functions which returns strings of variable length (I use gfortran)
Code:
[COLOR=#a020f0]module[/color] my_functions
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
[COLOR=#a020f0]contains[/color]    
  [COLOR=#a020f0]function[/color] first_n(s, n)
    [COLOR=#0000ff]! returns first N characters of the string[/color]
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=*[/b][/color]):: s
    [COLOR=#2e8b57][b]integer[/b][/color]::n
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color]n):: first_n
    first_n [COLOR=#804040][b]=[/b][/color] s([COLOR=#ff00ff]1[/color]:n)
  [COLOR=#a020f0]end function[/color] first_n

  [COLOR=#a020f0]function[/color] substring(s, from_pos, to_pos)
    [COLOR=#0000ff]! returns substring from the given position to the given position[/color]
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=*[/b][/color]):: s
    [COLOR=#2e8b57][b]integer[/b][/color]:: from_pos, to_pos
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color]to_pos [COLOR=#804040][b]-[/b][/color] from_pos [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]):: substring
    substring [COLOR=#804040][b]=[/b][/color] s(from_pos : to_pos)
  [COLOR=#a020f0]end function[/color] substring

[COLOR=#a020f0]end module[/color] my_functions

[COLOR=#a020f0]program[/color] strings
    [COLOR=#a020f0]use[/color] my_functions

    [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=*[/b][/color]), [COLOR=#2e8b57][b]parameter[/b][/color] :: inputString [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]"Fortran is old programming language"[/color]
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]7[/color])::outputString1
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]2[/color])::outputString2    

    outputString1 [COLOR=#804040][b]=[/b][/color] first_n(inputString, [COLOR=#ff00ff]7[/color])
    [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"output1 = '"[/color], outputString1,[COLOR=#ff00ff]"'"[/color]

    outputString2 [COLOR=#804040][b]=[/b][/color] substring(inputString, [COLOR=#ff00ff]9[/color], [COLOR=#ff00ff]10[/color])
    [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"output2 = '"[/color], outputString2,[COLOR=#ff00ff]"'"[/color]

    [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"output3 = '"[/color], substring(inputString, [COLOR=#ff00ff]12[/color], [COLOR=#ff00ff]14[/color]),[COLOR=#ff00ff]"'"[/color]
[COLOR=#a020f0]end program[/color] strings

Output:
Code:
$ strings
 output1 = 'Fortran'
 output2 = 'is'
 output3 = 'old'

But note:
I need to declare the length of the output-string exactly before assigning the result of the string function in it.
If I try to define it variable e.g. instead of
Code:
character(len=2)::outputString2
something like this
Code:
character(len=*)::outputString2
I get an compile error:
Code:
$ gfortran strings.f90 -o strings
strings.f90:30.35:

    character(len=*)::outputString2    
                                  1
Error: Entity with assumed character length at (1) must be a dummy argument or   PARAMETER
 
I added the function my_trim(), which i created using intrinsic trim() :)
Code:
[COLOR=#a020f0]module[/color] my_functions
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
[COLOR=#a020f0]contains[/color]    
  [COLOR=#a020f0]function[/color] first_n(s, n)
    [COLOR=#0000ff]! returns first N characters of the string[/color]
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=*[/b][/color]):: s
    [COLOR=#2e8b57][b]integer[/b][/color]::n
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color]n):: first_n
    first_n [COLOR=#804040][b]=[/b][/color] s([COLOR=#ff00ff]1[/color]:n)
  [COLOR=#a020f0]end function[/color] first_n

  [COLOR=#a020f0]function[/color] substring(s, from_pos, to_pos)
    [COLOR=#0000ff]! returns substring from the given position to the given position[/color]
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=*[/b][/color]):: s
    [COLOR=#2e8b57][b]integer[/b][/color]:: from_pos, to_pos
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color]to_pos [COLOR=#804040][b]-[/b][/color] from_pos [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]):: substring
    substring [COLOR=#804040][b]=[/b][/color] s(from_pos : to_pos)
  [COLOR=#a020f0]end function[/color] substring

  [COLOR=#a020f0]function[/color] my_trim(s)
    [COLOR=#0000ff]! returns substring from the given position to the given position[/color]
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=*[/b][/color]):: s
    [COLOR=#2e8b57][b]integer[/b][/color]:: n 
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#008080]len[/color]([COLOR=#008080]trim[/color](s))):: my_trim
    my_trim [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]trim[/color](s)
  [COLOR=#a020f0]end function[/color] my_trim

[COLOR=#a020f0]end module[/color] my_functions

[COLOR=#a020f0]program[/color] strings
    [COLOR=#a020f0]use[/color] my_functions

    [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=*[/b][/color]), [COLOR=#2e8b57][b]parameter[/b][/color] ::  inputString [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]"Fortran is old programming language"[/color]
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=*[/b][/color]), [COLOR=#2e8b57][b]parameter[/b][/color] ::  blah [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]" Blah Blah Blah                "[/color]
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]7[/color])::outputString1
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]len[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]2[/color])::outputString2    

    outputString1 [COLOR=#804040][b]=[/b][/color] first_n(inputString, [COLOR=#ff00ff]7[/color])
    [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"output1 = '"[/color], outputString1,[COLOR=#ff00ff]"'"[/color]

    outputString2 [COLOR=#804040][b]=[/b][/color] substring(inputString, [COLOR=#ff00ff]9[/color], [COLOR=#ff00ff]10[/color])
    [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"output2 = '"[/color], outputString2,[COLOR=#ff00ff]"'"[/color]

    [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"output3 = '"[/color], substring(inputString, [COLOR=#ff00ff]12[/color], [COLOR=#ff00ff]14[/color]),[COLOR=#ff00ff]"'"[/color]

    [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]"Trimmed '"[/color], blah, [COLOR=#ff00ff]"' = '"[/color], my_trim(blah),[COLOR=#ff00ff]"'"[/color]
[COLOR=#a020f0]end program[/color] strings

If I try it to compile with gforran I get an error on the last program line where I call this function
Code:
$ gfortran strings.f90 -o strings
strings.f90: In function 'strings':
strings.f90:48: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <[URL unfurl="true"]http://gcc.gnu.org/bugs.html>[/URL] for instructions.

But if I try it to compile with g95 it compiles without error
Code:
$ g95 strings.f90 -o strings
and works:
Code:
$ strings
 output1 = 'Fortran'
 output2 = 'is'
 output3 = 'old'
 Trimmed ' Blah Blah Blah                ' = ' Blah Blah Blah'
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top