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!

FORTRAN 77: an annoying space at the beginning of OUTPUT each line

Status
Not open for further replies.

jessicaj

Programmer
Aug 10, 2010
4
US
i need to have my data written in an output file. but when i write them using "write" statement, fortran 77 adds a "space" at the beginning of each line whereas i have to have each line without this "space" at the beginning.
in addition, my data in output file must include text and integers with different numbers of digits, and integers must be separated by a space from eachother so that each line includes different numbers of integers. THUS, i can't use "format" for writing this data as usual.
PLEASE HELP ME HOW TO GET RID OF THE SPACE AT THE BEGINNING OF EACH OUTPUT LINE!
 
You can prefix the line with char(13) - a carriage return. Try something like this - a bit long winded but it will do the job
Code:
      program packed
      ! If you do not wish to pass line and linepos every time
      ! use a common block
      integer LINEMAX, linepos
      parameter (LINEMAX = 80)
      character(len=LINEMAX) line

      ! Sorry, I don't know the lyrics
      ! Difficult to think of a sentence with numbers early in the morning
      integer VERSEMAX, versepos
      parameter (VERSEMAX=3)
      character*32 versestr(VERSEMAX)
      integer versenum(VERSEMAX)
      data versestr /
     * 'On the',  'th day of Christmas ...', ' maids a milking' /
      data versenum /12, 9, 0 /
      
      call LineClear (line, linepos)
      call LineStr (line, linepos, 'Today is the')
      call LineNum (line, linepos, 11)
      call LineStr (line, linepos, 'th of August')
      call LineNum (line, linepos, 2010)
      call LinePrint (line)
      
      call LineClear(line, linepos)
      do ii = 1, VERSEMAX - 1
         call LineStr (line, linepos, versestr(ii))
         call LineNum (line, linepos, versenum(ii))
      end do
      call LineStr (line, linepos, versestr(VERSEMAX))
      call LinePrint (line)
      
      stop
      end
      
      ! Clear the line, start with a CR to remove the leading space
      subroutine LineClear (var_line, out_linepos)
      character*(*) var_line
      integer out_linepos
      var_line(1:1) = char(13)
      out_linepos = 2
      end subroutine LineClear
      
      ! Catenate a string to the line
      subroutine LineStr (var_line, var_linepos, in_str)
      character*(*) var_line
      integer var_linepos
      character*(*) in_str
      
      var_line(var_linepos:) = in_str
      var_linepos = len_trim(var_line) + 1
      end subroutine LineStr
      
      ! Catenate a number to the line
      subroutine LineNum (var_line, var_linepos, in_num)
      character*(*) var_line
      integer var_linepos
      integer in_num
      ! Assuming no negative numbers
      if (in_num .lt. 10) then
         write (var_line(var_linepos:), '(I2)') in_num
      else if (in_num .lt. 100) then
         write (var_line(var_linepos:), '(I3)') in_num
      else if (in_num .lt. 1000) then
         write (var_line(var_linepos:), '(I4)') in_num
      else
         write (var_line(var_linepos:), '(I5)') in_num
      end if
      var_linepos = len_trim(var_line) + 1
      end subroutine LineNum
      
      ! Print the line
      subroutine LinePrint (in_line)
      character*(*) in_line
      write (*,*) in_line
      end subroutine LinePrint
 
If you use a '*' as format in the write statement, then the compiler is free to decide the final output form. Usually, it inserts a space at the beginning because the first character was used, in the past, to control the printer.

The solution proposed by xwb is globally a good idea, especially for complex output lines, but several things are useless or to complicated :
- the WRITE statement of the subroutine LinePrint which should be :
Code:
write (*,'(a)') in_line
. This is enough to delete the first space.
- starting each line by CHAR(13) is really a bad idea !
- if your compiler is relatively recent (like gfortran, g95, nag, intel ifort ...), you can take advantage of the format I0 to print out an integer with the right number of digits.
- in addition, you might take advantage of "advance='no'" in the write statement

So, with a recent FORTRAN compiler, I would write the previous example as follows :

Code:
      program packed
      
      implicit none
      
      integer VERSEMAX, versepos
      parameter (VERSEMAX=3)
      character*32 versestr(VERSEMAX)
      integer versenum(VERSEMAX),i
      data versestr /
     * 'On the ','th day of Christmas ...',' maids a milking'/
      data versenum /12, 9, 0 /
      
      write(*,'(A)',advance='no') 'Today is the '
      write(*,'(I0)',advance='no') 11
      write(*,'(A)',advance='no') 'th of August '
      write(*,'(I0)') 2010

      do i = 1, VERSEMAX-1
         write(*,'(A)',advance='no') TRIM(versestr(i))
         write(*,'(1X,I0,1X)',advance='no') versenum(i)
      end do
      
      write(*,'(A)') TRIM(versestr(VERSEMAX))

      end
 
Is format I0 standard or vendor specific? When I've tried it in the past (on F77/F90), it seemed to be vendor specific.
 
I believe that the format I0 has been introduced by the FORTRAN-95.

So it is not vendor specific and most of present FORTRAN compilers implement it.
 
thanx you all buddies!
but my output file does not include character type and it also contain integers. so the solutions you gave me is not efficient.
however, i found the solution using sed in unix. i omitted all first blanks in my output file using an sed command.

sed 's/^ *//'<in.asc>out.asc
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top