Je veux lire des données à partir d'un fichier dans lequel chaque ligne a un nombre différent de données, par exemple
15 format(T8,CV(i,1)(I7)) 1 Error: Unexpected element âCâ in format string at (1)
et j'ai besoin d'avoir un format comme ce format (T8,
quel
est un spécificateur de format dynamique déterminé au moment de l'exécution qui spécifie le nombre de colonnes dans une ligne du fichier d'entrée.
C'est le code que je souhaite modifier. Le code fonctionnait dans Intel fortran, mais dans gfortran j'ai eu une erreur.
do i=1,N read(20,'(I7)') CV(i,1) backspace(20) 15 format(T8,CV(i,1)(I7)) read(20,15) CV(i,2:CV(i,1)+1) end do
Le message d'erreur est
a b c d e f h g k
3 Réponses :
Vous n'avez pas besoin d'un format de variable pour ce faire.
Lors du traitement d'une liste d'entrée, toutes les valeurs requises pour traiter un élément d'entrée sont déterminées au début du traitement de cet élément. Dans ce cas, il est possible d'utiliser le premier élément d'une ligne pour déterminer les éléments du tableau à lire:
read(20, '(*(I7))') CV(i,1), CV(i,2:CV(i,1)+1)
Le spécificateur de répétition ("nombre d'éléments à lire" aspect) du format, dans ce cas ce que signifie la tentative d'utilisation de CV (i, 1)
, n'a pas besoin de correspondre au nombre d'éléments: il doit juste être plus grand (dans ce case *
signifiant "illimité"). Lorsque tous les éléments de la liste ont été lus, le traitement s'arrête.
Cela peut être fait en construisant un format via une écriture interne comme suit:
character(Len=30) :: form do i=1,N read(20,'(I7)') CV(i,1) write( form, '(a,i0,a)' ) '(', CV(i,1), 'i7)' backspace(20) read(20,form) CV(i,2:CV(i,1)+1) end do
Afin d'éviter le RETOUR ARRIÈRE, qui peut prendre beaucoup de temps, je préfère souvent lire l'entrée dans une ligne de caractères, que je peux ensuite analyser rapidement. Dans votre cas spécifique, comme le nombre de données d'entrée est toujours donné comme élément de données 1, la réponse donnée par @francescalus est parfaitement correcte. Si les lignes varient plus radicalement, vous pouvez développer le code suivant (qui ne fait actuellement que votre exemple)
program read_data ! integer, parameter :: MAX_DATA=10 integer, parameter :: MAX_ROWS=4 integer :: ios integer :: i character(len=18+7*MAX_DATA) :: line integer, dimension(MAX_ROWS, MAX_DATA) :: cv ! cv(:,:) = 0 open(unit=20, file='data.txt') main_loop: do i=1, 4 read(20, '(a)', iostat=ios) line if(is_iostat_end(ios)) exit main_loop read(line(1:len_trim(line)),'(*(i2))', iostat=ios) cv(i,1), cv(i,2:cv(i,1)+1) if(.not.(ios==0 .or. is_iostat_end(ios))) exit main_loop write(*,*) i,cv(i,1), cv(i,1:6) enddo main_loop ! end program read_data
@francescalus
format 15 (T8, CV (i, 1) (I7)) Erreur: élément «C» inattendu dans la chaîne de format à (1)