?

Log in

No account? Create an account
 
 
11 March 2009 @ 11:33 am
"write" without that damned first space  
Hello Fortran LJ group! I've been programming for 20+ years, and have been using fortran for most of them, and I have yet to find an elegant solution to this problem:

Many ASCII-based geometry file formats are picky about spaces: no leading spaces, no spaces between some number and a control character, etc. I specifically mean .vtk and .obj:

v 0.0 0.1 1.0
v 1.0 0.0 1.0
v 1.0 0.1 1.0
vn 0 0 1
f 1//1 2//1 3//1


Throw in some spaces, and most programs bomb.

Anyways, the only way that I've found to get rid of that awful leading first space is by putting text right into the format string:

write(99,'("v ",e12.6,1x,e12.6,1x,e12.6)') x(:,i)

Gotta love all those redundant characters.

But the real problem arises when trying to write the f 1//1 strings. Do I really need to print each integer to a character array using its own write statement, then adjustl each of them and concatenate them into a single string, THEN cram those onto a single line with a specially-made format string? This is beyond silly.

  integer :: i1,i2,i3,i4,i5,i6
  character(len=7) :: str1,str2
  character(len=18) :: stra,strb,strc
  character(len=57) :: str
  character(len=10) :: fstr

  i1 = 41
  i2 = 2
  i3 = 42
  i4 = 2
  i5 = 43
  i6 = 3

  write(str1,'(i7)') i1
  write(str2,'(i7)') i2
  write(stra,*) (str1//"//"//adjustl(str2))

  write(str1,'(i7)') i3
  write(str2,'(i7)') i4
  write(strb,*) (str1//"//"//adjustl(str2))

  write(str1,'(i7)') i5
  write(str2,'(i7)') i6
  write(strc,*) (str1//"//"//adjustl(str2))

  write(str,*) (trim(adjustl(stra))//" "//trim(adjustl(strb))//" "//trim(adjustl(strc)))

  if (len_trim(str) > 99) then
    write(fstr,'("(a",i3,")")') len_trim(str)
  else if (len_trim(str) > 9) then
    write(fstr,'("(a",i2,")")') len_trim(str)
  else
    write(fstr,'("(a",i1,")")') len_trim(str)
  endif
  write(*,'("f")',advance="no")
  write(*,fstr) str


% gfortran test.f90; a.out 
f 41//2 42//2 43//3


For real?
 
 
 
minzastrominzastro on March 12th, 2009 11:20 am (UTC)
Tricky.
Fortran is really not so good for strings sometimes.
Seems like the easiest way is to move this mess into subroutine.
But... why on Earth do You use Fortran for VTK??? =)
minzastrominzastro on March 12th, 2009 11:27 am (UTC)
by the way. Try this:
http://amcg.ese.ic.ac.uk/index.php?title=Local:Fortran_interface_for_writing_VTK_files
or this (seems that file is yet not there for download, but You can try to reach the authors):
http://code.google.com/p/lib-vtk-io/
Technolopetechnolope on March 12th, 2009 01:11 pm (UTC)
Those look like they'll help.

I'm mainly doing what they do: write back-end CFD codes that can dump data into a variety of formats.

Thanks for the links. I'm glad somebody was watching.
ext_232701 on April 26th, 2010 11:04 am (UTC)
Hi, why don't you use the variable length identifier i0 introduced by fortran95 or 2003?
Try something like that
write('99,'("f",3(X,i0,"//",i0))').

Also your first format string can be shortend to
("v",3(X,e12.6)) or maybe ("v",3(X,f0.1)) to make it more look like the example?

Regards and HTH,
Mike