Besoin d'aide pour Allocatable Array dans FORTRAN
-
03-07-2019 - |
Question
J'ai vraiment des problèmes avec Allocatable array.
Je dois copier toutes les informations d'un fichier dans un tableau allocatable. Le fichier est comme ça:
3
3 5
2 1
4 0
3 est le nombre de points Les six autres chiffres indiquent les points sur le graphique sous forme (x, y). Donc (3,5), (2, 1), (4,0) sont les points. Mais j'ai un problème pour faire ce nombre en paire.
J'ai essayé de coder, et voici mon codage:
PROGRAM practice
IMPLICIT NONE
INTEGER :: astat, ioStatus
INTEGER :: x, y
INTEGER :: num, code1, code2, code3, code4, code5, code6
! num shows number of location. in this case 3
! code 1 to 6 shows x and y variable. and code1 and 2 have to be paired.
! as well as this, code 3 and 4, code 5 and 6 have to be paired
! Declare TYPE
! set 1 to 3 show pair of (x, y)
TYPE Location
INTEGER :: set1, set2, set3
INTEGER :: num_locations
END TYPE
! Array ()
! for number of locations to visit
TYPE(Location), DIMENSION(:) :: numLocationArray(1000)
! allocatable array
! For locations
TYPE(Location), DIMENSION(:, :) :: LocationArray
ALLOCATABLE :: LocationArray
! allocate LocationArray
ALLOCATE(LocationArray(x, y), STAT = astat)
IF (astat < 0) STOP "allocate failed"
! open input file to copy info into array
OPEN (UNIT = 10, File ="input.txt", STATUS = "OLD", ACTION = "READ", &
IOSTAT = ioStatus)
IF (ioStatus < 0) STOP "open failed"
! format of the file
100 FORMAT (I1, /, 2I2, /, 2I2, / 2I2)
! Do loop to set table
DO x = 0, size(LocationArray), 1
READ (UNIT = 10, FMT = 100, IOSTAT = ioStatus) num, code1, code2, &
code3, code4, code5, code6
! check whether program read file correctly (option)
PRINT *, num, code1, code2, code3, code4, code5, code6
IF (x == code1) THEN
DO y = 0, size(LocationArray), 1
IF (y == code2) THEN
LocationArray%set1 = LocationArray(x, y)
! check whether copied correctly
PRINT *, LocationArray(x, y)
PRINT *, LocationArray%set1
END IF
END DO
END IF
END DO
! ==============
! execution part
! ==============
! instructions:
! use pointer to do excecution
! read allocatable array above
! do excecution (distance) ** do not forget to go back to the original place (0,0)
! ** do not forget to try every single possible way
! when get total distance, do distance times 2 and figure out cost
! print all info (cost, distance, and steps)
! (example of output)
! The minimum cost is 36
! The distance travelled is 18
! Step 1: Start at ( 0, 0)
! Step 2: Goes to ( 2, 1)
! Step 3: Goes to ( 3, 5)
! Step 4: Goes to ( 4, 0)
! Step 5: Ends at ( 0, 0)
END PROGRAM
Ce programme ne fonctionne pas ... J'ai une erreur:
LocationArray%set1 = LocationArray(x, y)
Error: Can't convert TYPE(location) to INTEGER(4) at (1)
Je me suis fatigué pour comprendre cette erreur, mais je ne pouvais pas Quelqu'un a-t-il un conseil ou une suggestion à propos de mon codage?
Pardonnez mon anglais, je suis japonais.
Si quelqu'un a des questions à propos de ma question (je veux dire qu'il faut plus d'explications), merci de me le faire savoir.
Merci. Uka
La solution
Dans la définition du type Location
, vous avez indiqué que set1, set2 et set3 sont des variables entières, puis vous essayez de lui affecter un tableau. Je pense que ce que vous voulez, puisque ce sont des paires, est d’avoir set1, set2 et set3 un tableau entier de taille 2.
Que se passe-t-il si vous modifiez le type Emplacement
pour qu'il soit:
TYPE Location
INTEGER, DIMENSION(2) :: set1, set2, set3
INTEGER :: num_locations
END TYPE
De plus, la boucle pour lire les données n'a aucun sens pour moi. Je pense que je l’écrirais ainsi (notez que les tableaux de Fortran sont basés sur 1 par défaut et non sur zéro comme en C):
DO x = 1, size(numLocationArray), 1
READ (UNIT = 10, FMT = 100, IOSTAT = ioStatus) num, code1, code2, &
code3, code4, code5, code6
! check whether program read file correctly (option)
PRINT *, num, code1, code2, code3, code4, code5, code6
numLocationArray(x)%num_locations = num
numLocationArray(x)%set1(0) = code1
numLocationArray(x)%set1(1) = code2
numLocationArray(x)%set2(0) = code3
numLocationArray(x)%set2(1) = code4
numLocationArray(x)%set3(0) = code5
numLocationArray(x)%set3(1) = code6
END DO
Vous devrez évidemment faire quelque chose pour détecter et gérer la condition de fin de fichier.
Si le nombre d'emplacements est vraiment illisible, vous devez procéder comme suit:
TYPE Coordinate
INTEGER :: x
INTEGER :: y
END TYPE
TYPE Locations
TYPE(Coordinate), DIMENSION(:), ALLOCATABLE :: location
INTEGER :: num_locations
END TYPE
TYPE(Location), DIMENSION(:) :: numLocationArray(1000)
! open input file to copy info into array
OPEN (UNIT = 10, File ="input.txt", STATUS = "OLD", ACTION = "READ", &
IOSTAT = ioStatus)
IF (ioStatus < 0) STOP "open failed"
! format of the file
100 FORMAT (I1 )
200 FORMAT (2I2)
DO n = 1, size(numLocationArray), 1
READ (UNIT = 10, FMT = 100, IOSTAT = iostatus) num
numLocationArray(n)%num_locations = num
ALLOCATE (numLocationArray(n)%locations(num), STAT = astat)
if (astat < 0) STOP 'allocate failed'
DO l = 1, num, 1
READ (UNIT = 10, FMT = 200, IOSTAT = iostatus) x, y
numLocationArray(n)%locations(l)%x = x
numLocationArray(n)%locations(l)%y = y
END DO
END DO
Autres conseils
On dirait que vous essayez de donner à un entier la valeur de deux entiers. C'est quelque chose comme vous essayez de faire = (ou var = 5,5).