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!

Declaring a DT Array of Variable Length

Status
Not open for further replies.

dac5039

Programmer
Aug 12, 2009
22
US
I have a data file containing over 100 years of high, low, and average temperature data which I want to read-in and assign to variables of ddt "temps."

type temps
integer :: dates, hi, lo, av
end type temps

So each date will have the three temperature values assigned to it for easy access. I need to store these data, however, and so I was going to create an array of length determined by first reading through the file and counting the lines. The problem is, I can't define an array of my derived type with a variable length...

length = 0
do
read(99,*,end=1)dates
length = length + 1
enddo

1 rewind(99)
type(temps) :: array(length)

The error at the command line is:

type(temps), pointer :: array(length)
1
Error: Unexpected data declaration statement at (1)

In reading my downloaded manual "Fortran 95," Martin Counihan, I see that I may need to use a pointer, or an array pointer? This is where I get confused... Should the pointer be defined as type "temps" or the target or both? Also, is my methodology ideal for the task?

Thanks for any insight!

Dave
 
I think, that you don't need pointer.
Post the short example of the data in the input file.
 
Data file. Goes through 20090718...

18960101 29 19 24 99 41 0.00 0.00
18960102 43 15 29 99 36 0.00 0.00
18960103 43 14 29 99 36 0.00 0.00
18960104 14 57 14 99 57 0.00 0.00
18960105 10 59 10 99 59 0.00 0.00
18960106 14 57 14 99 57 0.00 0.00
18960107 21 11 16 99 49 0.00 0.00
18960108 26 12 19 99 46 0.00 0.00
18960109 31 20 26 99 39 0.05 0.50
18960110 31 22 27 99 38 0.00 0.00
18960111 28 21 25 99 40 0.00 0.00
18960112 42 23 33 99 32 0.00 0.00

Would a different format be easier to work with? Like one with no whitespace? I'm slowly adjusting my mindset from Perl to Fortran
 
Hi dac5039,

you want four compoenents datastruct, but your line
(dates, hi, lo, av), but your data line is longer
18960101 29 19 24 99 41 0.00 0.00
i.e
dates = 18960101
hi = 29
low = 19
av = 24

are the other data i.e 99 41 0.00 0.00
irrelevant ?
 
This does what you want
tdata.f90
Code:
[COLOR=#a020f0]module[/color] my_temperatures
  [COLOR=#2e8b57][b]type[/b][/color] temps
    [COLOR=#2e8b57][b]integer[/b][/color] :: dates, hi, lo, av
  [COLOR=#2e8b57][b]end type[/b][/color] temps
[COLOR=#a020f0]contains[/color]
  [COLOR=#a020f0]subroutine[/color] file2array(fname, array)
    [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#804040][b]*[/b][/color]), [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]in[/b][/color]) :: fname
    [COLOR=#2e8b57][b]type[/b][/color](temps), [COLOR=#2e8b57][b]allocatable[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color](:), [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]in[/b][/color] [COLOR=#2e8b57][b]out[/b][/color]) :: array
    [COLOR=#2e8b57][b]integer[/b][/color] :: i, nr_lines, nr_elements, stat
    [COLOR=#2e8b57][b]type[/b][/color](temps) :: dummy

    [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]"Reading the Data from file '"[/color], fname, [COLOR=#ff00ff]"' :"[/color] 
    [COLOR=#804040][b]open[/b][/color]([COLOR=#ff00ff]1[/color],[COLOR=#804040][b]file[/b][/color][COLOR=#804040][b]=[/b][/color]fname,[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]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]) fname, [COLOR=#ff00ff]' cannot be opened !'[/color]
      [COLOR=#804040][b]go to[/b][/color] [COLOR=#ff00ff]20[/color]   
    [COLOR=#804040][b]end if[/b][/color]

    [COLOR=#0000ff]! count number of lines in the file[/color]
    nr_lines [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color]
    [COLOR=#804040][b]do[/b][/color]
      [COLOR=#804040][b]read[/b][/color]([COLOR=#ff00ff]1[/color],[COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]end[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#804040][b]10[/b][/color],[COLOR=#804040][b]err[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#804040][b]20[/b][/color]) dummy
      nr_lines [COLOR=#804040][b]=[/b][/color] nr_lines [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
    [COLOR=#804040][b]end do[/b][/color]

    [COLOR=#0000ff]! rewind back to the beginning of the file for unit=1[/color]
    [COLOR=#ff00ff]10[/color] [COLOR=#804040][b]rewind[/b][/color]([COLOR=#ff00ff]1[/color])
    [COLOR=#0000ff]! number of array elements = number of data lines in the file[/color]
    nr_elements[COLOR=#804040][b]=[/b][/color]nr_lines
    [COLOR=#0000ff]! allocate the arrays of given size [/color]
    [COLOR=#804040][b]allocate[/b][/color] (array(nr_elements))

    [COLOR=#0000ff]! read array elements from the file[/color]
    [COLOR=#804040][b]do[/b][/color] i [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]1[/color], nr_elements
      [COLOR=#804040][b]read[/b][/color]([COLOR=#ff00ff]1[/color],[COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]err[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#804040][b]20[/b][/color]) array(i)
      [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#ff00ff]'(a)'[/color],[COLOR=#804040][b]advance[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'no'[/color]) [COLOR=#ff00ff]'.'[/color]
    [COLOR=#804040][b]end do[/b][/color]
    [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#0000ff]! next line[/color]
    [COLOR=#804040][b]close[/b][/color]([COLOR=#ff00ff]1[/color])

    [COLOR=#0000ff]![/color]
    [COLOR=#ff00ff]20[/color] [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'End of Reading Data'[/color]
  [COLOR=#a020f0]end subroutine[/color] file2array

  [COLOR=#a020f0]subroutine[/color] array2screen(array_name, array)
    [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
    [COLOR=#2e8b57][b]integer[/b][/color] :: n, i
    [COLOR=#2e8b57][b]type[/b][/color](temps), [COLOR=#2e8b57][b]allocatable[/b][/color], [COLOR=#2e8b57][b]dimension[/b][/color](:), [COLOR=#2e8b57][b]intent[/b][/color]([COLOR=#2e8b57][b]in[/b][/color]) :: array
    [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#804040][b]*[/b][/color]) :: array_name

    [COLOR=#0000ff]! process only if the array is allocated[/color]
    [COLOR=#804040][b]if[/b][/color] ([COLOR=#008080]allocated[/color](array)) [COLOR=#804040][b]then[/b][/color]
      n [COLOR=#804040][b]=[/b][/color] [COLOR=#008080]size[/color](array)
      [COLOR=#804040][b]do[/b][/color] i [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]1[/color], n
        [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) array_name, [COLOR=#ff00ff]'['[/color], i, [COLOR=#ff00ff]'] = '[/color], array(i)
      [COLOR=#804040][b]end do[/b][/color]
    [COLOR=#804040][b]else[/b][/color]
      [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Error: Argument Array not allocated !'[/color]
    [COLOR=#804040][b]end if[/b][/color]
  [COLOR=#a020f0]end subroutine[/color] array2screen
  
[COLOR=#a020f0]end module[/color] my_temperatures

[COLOR=#a020f0]program[/color] tdata
  [COLOR=#a020f0]use[/color] my_temperatures

  [COLOR=#2e8b57][b]type[/b][/color](temps), [COLOR=#2e8b57][b]dimension[/b][/color](:), [COLOR=#2e8b57][b]allocatable[/b][/color] :: temperatures_array
  [COLOR=#2e8b57][b]integer[/b][/color] :: i

  [COLOR=#0000ff]! read data from the input file into an array[/color]
  [COLOR=#a020f0]call[/color] file2array([COLOR=#ff00ff]'tdata.txt'[/color], temperatures_array)
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#0000ff]! next line [/color]

  [COLOR=#0000ff]! print array to the screen[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Array of all temperatures: '[/color]
  [COLOR=#a020f0]call[/color] array2screen([COLOR=#ff00ff]'temperature'[/color], temperatures_array)
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color])  

  [COLOR=#0000ff]! Working with components of an array element[/color]
  i [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]3[/color]
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Date   : '[/color], temperatures_array(i)%dates
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Temperature : '[/color]
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Hi     : '[/color], temperatures_array(i)%hi
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Low    : '[/color], temperatures_array(i)%lo
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'Average: '[/color], temperatures_array(i)%av
[COLOR=#a020f0]end program[/color] tdata
Output:
Code:
$ g95 tdata.f90 -o tdata

$ tdata
 Reading the Data from file 'tdata.txt' :
............
 End of Reading Data

 Array of all temperatures: 
 temperature[ 1 ] =  18960101 29 19 24
 temperature[ 2 ] =  18960102 43 15 29
 temperature[ 3 ] =  18960103 43 14 29
 temperature[ 4 ] =  18960104 14 57 14
 temperature[ 5 ] =  18960105 10 59 10
 temperature[ 6 ] =  18960106 14 57 14
 temperature[ 7 ] =  18960107 21 11 16
 temperature[ 8 ] =  18960108 26 12 19
 temperature[ 9 ] =  18960109 31 20 26
 temperature[ 10 ] =  18960110 31 22 27
 temperature[ 11 ] =  18960111 28 21 25
 temperature[ 12 ] =  18960112 42 23 33

 Date   :  18960103
 Temperature : 
 Hi     :  43
 Low    :  14
 Average:  29
 
mikrom,

This was extremely clear and helpful, thank you!

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top