53

我在 Fortran 中有一个程序,可以将结果保存到文件中。目前我使用打开文件

OPEN (1, FILE = 'Output.TXT')

但是,我现在想运行一个循环,并将每次迭代的结果保存到文件'Output1.TXT''Output2.TXT''Output3.TXT'等。

Fortran 中是否有一种简单的方法可以从循环计数器构造文件名i

4

9 回答 9

60

你可以写一个单元,但你也可以写一个字符串

program foo
    character(len=1024) :: filename

    write (filename, "(A5,I2)") "hello", 10

    print *, trim(filename)
end program

请注意(这是我所说的第二个技巧)您还可以通过编程方式构建格式字符串。

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
于 2009-08-11T20:29:28.970 回答
22

一个更简单的解决方案恕我直言......................

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
于 2011-04-29T09:03:48.173 回答
13

那么这是一个简单的函数,它将返回整数的左对齐字符串版本:

character(len=20) function str(k)
!   "Convert an integer to string."
    integer, intent(in) :: k
    write (str, *) k
    str = adjustl(str)
end function str

这是一个测试代码:

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
于 2013-05-08T10:10:08.157 回答
8

我已经在 SO 的其他地方展示了这个(如何在格式说明符语句中使用变量?,而不是完全重复的恕我直言),但我认为将它放在这里是值得的。可以使用此问题的其他答案中的技术来制作一个简单的功能

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

您可以在之后使用它,而无需担心修剪和左调整,也无需写入临时变量:

OPEN(1, FILE = 'Output'//itoa(i)//'.TXT')

由于可分配字符串,它需要 Fortran 2003。

于 2015-06-24T13:38:47.133 回答
3

对于缩短版本。如果所有索引都小于 10,则使用以下命令:

do i=0,9
   fid=100+i
   fname='OUTPUT'//NCHAR(i+48) //'.txt'
   open(fid, file=fname)
   !....
end do

对于一般版本:

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

就这样。

于 2014-11-19T06:36:48.873 回答
0

我已经尝试过@Alejandro 和@user2361779,但它给了我一个不满意的结果,例如file 1.txtorfile1 .txt而不是file1.txt. 但是我找到了更好的解决方案:

...
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))
...

解释:

例如设置i = 10write(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

我认为这是一个最简单的解决方案,它为您提供一个动态长度的文件名,而没有任何从整数到字符串转换过程的遗留空格。

于 2015-06-24T12:17:06.717 回答
0

尝试以下操作:

    ....
    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
    ....

其中“...”表示其他适合您目的的代码。

于 2018-04-28T16:18:19.480 回答
-2

要将整数转换为字符串:

integer :: i    
character* :: s    
if (i.LE.9) then
     s=char(48+i)    
else if (i.GE.10) then
     s=char(48+(i/10))// char(48-10*(i/10)+i)    
endif
于 2016-05-05T23:55:02.243 回答
-3

这是我解决这个问题的子程序。它将 0 : 9999 范围内的整数转换为字符。例如,将 INTEGER 123 转换为字符 0123。希望对您有所帮助。

PS - 抱歉评论;它们在罗马尼亚语中很有意义:P

 subroutine nume_fisier (i,filename_tot)

   implicit none
   integer :: i

   integer :: integer_zeci,rest_zeci,integer_sute,rest_sute,integer_mii,rest_mii
   character(1) :: filename1,filename2,filename3,filename4
   character(4) :: filename_tot

! Subrutina ce transforma un INTEGER de la 0 la 9999 in o serie de CARACTERE cu acelasi numar

! pentru a fi folosite in numerotarea si denumirea fisierelor de rezultate.

 if(i<=9) then

  filename1=char(48+0)
  filename2=char(48+0)
  filename3=char(48+0)
  filename4=char(48+i)  

 elseif(i>=10.and.i<=99) then

  integer_zeci=int(i/10)
  rest_zeci=mod(i,10)
  filename1=char(48+0)
  filename2=char(48+0)
  filename3=char(48+integer_zeci)
  filename4=char(48+rest_zeci)

 elseif(i>=100.and.i<=999) then

  integer_sute=int(i/100)
  rest_sute=mod(i,100)
  integer_zeci=int(rest_sute/10)
  rest_zeci=mod(rest_sute,10)
  filename1=char(48+0)
  filename2=char(48+integer_sute)
  filename3=char(48+integer_zeci)
  filename4=char(48+rest_zeci)

 elseif(i>=1000.and.i<=9999) then

  integer_mii=int(i/1000)
  rest_mii=mod(i,1000)
  integer_sute=int(rest_mii/100)
  rest_sute=mod(rest_mii,100)
  integer_zeci=int(rest_sute/10)
  rest_zeci=mod(rest_sute,10)
  filename1=char(48+integer_mii)
  filename2=char(48+integer_sute)
  filename3=char(48+integer_zeci) 
  filename4=char(48+rest_zeci)

 endif

 filename_tot=''//filename1//''//filename2//''//filename3//''//filename4//''
 return
 end subroutine nume_fisier
于 2011-01-20T16:44:02.537 回答