tags:

views:

121

answers:

2

Apologies for the rather simple question, I just can't seem to find ANY good fortran docs.

I'm trying to write a function that reads from a unit, trims the output and appends the null terminator, something like:

character(*) function readCString()
  character*512 str
  read(1, *) str
  readCString = TRIM(str)//char(0)
  return
end function readCString

However, I KNOW this doesn't work yet it compiles. Segmentation faults have not been my friend recently. Without the "character(*)" before the function keyword it will not compile, and with any value in place of the star it also breaks, most likely because:

TRIM(str)//char(0)

is not the same length as the number I put in place of the star. I'm very new to fortran but am trying to interface some fortran code with C (hence the null terminator).

Thanks for any help.

+1  A: 

character(star) is not a good idea to use as a function return. character(star) is not a dynamic variable length string -- it means obtain the length from the caller. So I suggest either using a fixed length string as the function return, or using character(*) as a subroutine argument -- but in that case the caller has to reserve the memory in advance, which just pushes fixing the length to the caller. If you truly don't know the maximum length and must have a dynamicvariable length string, there are way to do it. There is a variable length string module. Fortran 2003 has allocatable scalers, though this isn't widely implemented. You could use an array of single characters -- allocatable arrays have been around a long time.

Here is an method that works as Fortran:

module test_func_mod
contains
function readCString()
  use iso_c_binding
  character (kind=c_char, len=512)  :: readCString
  character (kind=c_char, len=511) :: str
  read(1, *) str
  readCString = TRIM(str) // C_NULL_CHAR
  return
end function readCString

end module test_func_mod

program test

use test_func_mod

open (unit=1, file="temp.txt")
write (*, *) readCString()

end program test

If you want to interface Fortran and C, I recommend using the new ISO C Binding. It provides a standard and therefore portable method of interfacing Fortran and C or any language that uses C passing conventions. It is easier to use and less likely to break than the hacks that had to be used in the past. While officially part of Fortran 2003, it is already supported by numerous compilers. Strings used to be particularly difficult, with some compilers having hidden length arguments, etc. The ISO C Binding makes all of this transparent to the programmer. I remember giving some example code for a similar question (Fortran, C, and strings) on stackoverflow, but I can't find the question.

M. S. B.
+1 and some characters to pad out the comment
High Performance Mark
A: 

Hmm... It's been a while since I've done Fortran, and I've had to go hit Google to help, and yeah, there's a lot of conflicting information. One issue is that are frequently large differences between Fortran versions and individual compilers.

So question: what flavor of Fortran are you using?

One resource I've found that might help you is this one, which deals explicitly with passing strings from Fortran to C. It has a pretty good reference in general for it's particular compiler; I don't know if you're using it, but it might help.

Edit: Heh... sorry about the broken link. Fixed.

Randolpho