J'ai un programme en Fortran qui enregistre les résultats dans un fichier. Au moment où j'ouvre le fichier en utilisant
OPEN (1, FILE = 'Output.TXT')
Cependant, je souhaite maintenant exécuter une boucle et enregistrer les résultats de chaque itération dans les fichiers 'Output1.TXT'
, 'Output2.TXT'
, 'Output3.TXT'
, etc.
Existe-t-il un moyen simple dans Fortran de créer des noms de fichiers à partir du compteur de boucles i
?
vous pouvez écrire sur une unité, mais vous pouvez aussi écrire sur une chaîne
program foo
character(len=1024) :: filename
write (filename, "(A5,I2)") "hello", 10
print *, trim(filename)
end program
Veuillez noter (ceci est la deuxième astuce dont je parlais) que vous pouvez également créer une chaîne de format par programme.
program foo
character(len=1024) :: filename
character(len=1024) :: format_string
integer :: i
do i=1, 10
if (i < 10) then
format_string = "(A5,I1)"
else
format_string = "(A5,I2)"
endif
write (filename,format_string) "hello", i
print *, trim(filename)
enddo
end program
Une solution beaucoup plus facile IMHO ...................
character(len=8) :: fmt ! format descriptor
fmt = '(I5.5)' ! an integer of width 5 with zeros at the left
i1= 59
write (x1,fmt) i1 ! converting integer to string using a 'internal file'
filename='output'//trim(x1)//'.dat'
! ====> filename: output00059.dat
Eh bien voici une fonction simple qui retournera la version de chaîne d'un nombre entier justifiée à gauche:
character(len=20) function str(k)
! "Convert an integer to string."
integer, intent(in) :: k
write (str, *) k
str = adjustl(str)
end function str
Et voici un code de test:
program x
integer :: i
do i=1, 100
open(11, file='Output'//trim(str(i))//'.txt')
write (11, *) i
close (11)
end do
end program x
Je l'ai déjà montré ailleurs sur SO ( Comment utiliser une variable dans la déclaration de spécificateur de format? , ce n'est pas une copie IMHO exacte, mais je pense qu'il vaut la peine de la placer ici. Il est possible d’utiliser les techniques d’autres réponses pour cette question afin de créer une fonction simple.
function itoa(i) result(res)
character(:),allocatable :: res
integer,intent(in) :: i
character(range(i)+2) :: tmp
write(tmp,'(i0)') i
res = trim(tmp)
end function
que vous pouvez utiliser après sans vous soucier de l'ajustement et du réglage à gauche et sans écrire dans une variable temporaire:
OPEN(1, FILE = 'Output'//itoa(i)//'.TXT')
Il nécessite Fortran 2003 en raison de la chaîne pouvant être allouée.
Pour une version abrégée . Si tous les indices sont inférieurs à 10, utilisez les éléments suivants:
do i=0,9
fid=100+i
fname='OUTPUT'//NCHAR(i+48) //'.txt'
open(fid, file=fname)
!....
end do
Pour une version générale:
character(len=5) :: charI
do i = 0,100
fid = 100 + i
write(charI,"(A)"), i
fname ='OUTPUT' // trim(charI) // '.txt'
open(fid, file=fname)
end do
C'est tout.
Essayez ce qui suit:
....
character(len=30) :: filename ! length depends on expected names
integer :: inuit
....
do i=1,n
write(filename,'("output",i0,".txt")') i
open(newunit=iunit,file=filename,...)
....
close(iunit)
enddo
....
Où "..." signifie un autre code approprié à vos besoins.
J'ai déjà essayé @Alejandro et @ user2361779, mais cela me donne un résultat insatisfait tel que file 1.txt
ou file1 .txt
au lieu de file1.txt
. Cependant, je trouve la meilleure solution:
...
integer :: i
character(len=5) :: char_i ! use your maximum expected len
character(len=32) :: filename
write(char_i, '(I5)') i ! convert integer to char
write(filename, '("path/to/file/", A, ".dat")') trim(adjustl(char_i))
...
Explication:
par exemple. définir i = 10
et write(char_i, '(I5)') i
char_i gives " 10" ! this is original value of char_i
adjustl(char_i) gives "10 " ! adjust char_i to the left
trim(adjustl(char_i)) gives "10" ! adjust char_i to the left then remove blank space on the right
Je pense que ceci est une solution la plus simple qui vous donne un nom de fichier de longueur dynamique sans aucun espace vide hérité d'un processus de conversion d'entier à une chaîne.