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!

Beginner's simple program works but am sure there is a better way. 1

Status
Not open for further replies.

Me4President

Technical User
Sep 30, 2009
7
NL
Hi,
Sorry for the long post, but I thought as much info as possible would help...
I did 8 weeks of fortran77 at university last year, and was always terrible. But I have been trying to use it recently at work to automate a task, trying to format the contents of an ascii text file. I am doing it on a Red Hat Linux, using tutorials found online.

I have it working - but it is very ugly - and I am sure someone could help me improve the way I am doing it :D

First I use awk to select the numbers I need from an exported file. This is written to a file "awk_out"

Then I use fortran to read these 2 columns of data into the format I want.
I do get a (not-too-important) error at the end about reaching end of file, but it doesn't get written to the file I make,, so I dont mind it...
Code:
list in: end of file
apparent state: unit 60 named awk_out
last format: list io
lately reading sequential formatted external IO
Abort

I use a korn shell script to create the input file for fortran, compile, write the formatted output to a file, and then clean up a bit.

Code:
#!/usr/bin/ksh
echo Enter name of input file
read input
awk 'END { print NR > "awk_out" }' /$input
awk '{printf "%.0f %.0f\n", $1, $2 >> "awk_out" }' /$input
echo Enter name of output file
read output
g77 poly.f
/glb/home/nltme9/prog/a.out > $output
rm -rf awk_out
rm -rf a.out

What I really want is to be able to use an alias to run the fortran program from my terminal (in any directory I want to be in). Using an input file I specify, I want an output file in the format below - ideally also specifying what string to put at the start of each line...
Code:
POLGON  3974  1693  3877  1658  3818  1641  2461  1632  2405  1687  2347  1721

Any help would be greatly appreciated!
Thanks


Fortran:
Code:
      program poly
c
c  This program reads a data file of polygon
c  coordinates from 123di and converts them
c   for use in SIPMAP.
c   9/09
c
      implicit none
      integer file, n, i, j, lines, nmax, rem
      parameter (nmax=9999, file=60 )
      integer x(nmax), y(nmax)

c  Open the data file, previously made with awk
c  First line contains number of lines
      open (file, FILE='awk_out', STATUS='OLD')

c  Read the number of points on first line
c  calculate number of lines to be used
      read(file,*) n
      lines = n/6
      rem = n - lines*6
c      write(*,*) lines
c      write(*,*) rem

c  Do loop over the number of lines,
c  writing out 6 numbers per line in format specified @100
c  note continuation using & at position 6 of new line
      do 60 i= 1, lines
      read(file,*) x(i),y(i),x(i+1),y(i+1),x(i+2),y(i+2),x(i+3),y(i+3)
     &,x(i+4),y(i+4),x(i+5),y(i+5)
      write(*,100) x(i),y(i),x(i+1),y(i+1),x(i+2),y(i+2),x(i+3),y(i+3)
     &,x(i+4),y(i+4),x(i+5),y(i+5)
   60 continue

c  Deal with the last line...

      if (rem .eq. 1) then
      do 10 j=1, rem
      read(file,*) x(i),y(i)
      write(*,100) x(i),y(i)
   10 continue
      elseif (rem .eq. 2) then
      do 20 j=1, rem
      read(file,*) x(i),y(i),x(i+j),y(i+j)
      write(*,100) x(i),y(i),x(i+j),y(i+j)
   20 continue
      elseif (rem .eq. 3) then
      do 30 j=1, rem
      read(file,*) x(i),y(i),x(i+j),y(i+j),x(i+j),y(i+j)
      write(*,100) x(i),y(i),x(i+j),y(i+j),x(i+j),y(i+j)
   30 continue
      elseif (rem .eq. 4) then
      do 40 j=1, rem
      read(file,*) x(i),y(i),x(i+j),y(i+j),x(i+j),y(i+j),x(i+j),y(i+j)
      write(*,100) x(i),y(i),x(i+j),y(i+j),x(i+j),y(i+j),x(i+j),y(i+j)
   40 continue
      elseif (rem .eq. 5) then
      do 50 j=1, rem
      read(file,*) x(i),y(i),x(i+j),y(i+j),x(i+j),y(i+j),x(i+j),y(i+j)
      write(*,100) x(i),y(i),x(i+j),y(i+j),x(i+j),y(i+j),x(i+j),y(i+j)
   50 enddo
      endif

c  Format for writing lines
  100 format ('POLGON', 6(I6, I6))

c  Close the file
      close (file)

 9999 stop
      end

Is there some way I could use counting to do 6 pairs of numbers on each line, with POLGON at the beginning?
Also the only way I could think of getting the last line in the right format was to look after each possibility individually, but it just seems a horrible way of doing it...
 
Hi Me4President,

1. IMHO: if you parsed the numbers with awk, and you are sure that in your input file are only the numbers, then you don't need parse the numbers with fortran - instead you can process the input file line by line as characters and you don't need in the first line the number of all points (i.e numbers / 2)

2. On your place, I would use today rather more modern dialect of Fortran, better is Fortran90/95, available with the compilers g95 or gfortran. With these newer dialects you have far more intrinsic functions available - e.g. g77 doesn't have the function trim(),...etc.

But in the exampe below I assume that you have only g77. But with this compiler you can use instead of the default fixed-form rather the free-form.

Given is this file with numbers - without the count of points in the first line
poly_inp.txt
Code:
3974  1693  3877  1658  3818  1641  2461  1632  2405  1687  2347  1721
3974  1693  3877  1658  3818  1641  2461  1632  2405  1687  2347  1721
3974  1693  3877  1658
then this code does what you probably want
poly.for
Code:
[COLOR=#a020f0]program[/color] poly
[COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

[COLOR=#2e8b57][b]integer[/b][/color] stat
[COLOR=#0000ff]! 12 numbers of length 4 + 11 spaces of length 2 = 12*4 + 11*2 = 70[/color]
[COLOR=#2e8b57][b]character[/b][/color]([COLOR=#ff00ff]70[/color]) :: line

[COLOR=#804040][b]open[/b][/color] ([COLOR=#ff00ff]1[/color], [COLOR=#804040][b]file[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'poly_inp.txt'[/color], [COLOR=#804040][b]status[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'old'[/color], [COLOR=#804040][b]iostat[/b][/color][COLOR=#804040][b]=[/b][/color]stat)
[COLOR=#804040][b]open[/b][/color] ([COLOR=#ff00ff]2[/color], [COLOR=#804040][b]file[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'poly_out.txt'[/color], [COLOR=#804040][b]status[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'unknown'[/color])
[COLOR=#804040][b]if[/b][/color] (stat [COLOR=#804040][b].ne.[/b][/color] [COLOR=#ff00ff]0[/color]) [COLOR=#804040][b]then[/b][/color]
[COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'File cannot be opened !'[/color]
  [COLOR=#804040][b]go to[/b][/color] [COLOR=#ff00ff]99[/color]
[COLOR=#804040][b]end if[/b][/color]


[COLOR=#804040][b]do[/b][/color] [COLOR=#804040][b]while[/b][/color] ([COLOR=#ff00ff].true.[/color]) 
  [COLOR=#804040][b]read[/b][/color]([COLOR=#ff00ff]1[/color], [COLOR=#ff00ff]'(A)'[/color], [COLOR=#804040][b]end[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#804040][b]99[/b][/color]) line 
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'(78A)'[/color]) [COLOR=#ff00ff]'POLGON  '[/color], line [COLOR=#0000ff]! write on screen[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#ff00ff]2[/color], [COLOR=#ff00ff]'(78A)'[/color]) [COLOR=#ff00ff]'POLGON  '[/color], line [COLOR=#0000ff]! write to file[/color]
[COLOR=#804040][b]enddo[/b][/color]

[COLOR=#6a5acd]99[/color] [COLOR=#804040][b]continue[/b][/color]
[COLOR=#804040][b]close[/b][/color]([COLOR=#ff00ff]1[/color])
[COLOR=#804040][b]close[/b][/color]([COLOR=#ff00ff]2[/color])
[COLOR=#a020f0]end program[/color] poly
Compilation and output:
Code:
$ g77 poly.for -o poly -ffree-form

$ poly
POLGON  3974  1693  3877  1658  3818  1641  2461  1632  2405  1687  2347  1721
POLGON  3974  1693  3877  1658  3818  1641  2461  1632  2405  1687  2347  1721
POLGON  3974  1693  3877  1658
You get the output in the file poly_out.txt too.

Finally, Fortran is primarily for scientific computations and it's not very well suited for processing text files. If you would rather use one of the modern scripting languages available (e.g. Perl, Python, Ruby, Tcl/Tk, ...), you don't need call awk before the main processing and you could do all your work in one program.
Here on Tek-Tips, there are good forums for the above scripting languages.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top