Convert integers to strings to create output filenames at run time

匿名 (未验证) 提交于 2019-12-03 02:35:01

问题:

I have a program in Fortran that saves the results to a file. At the moment I open the file using

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

However, I now want to run a loop, and save the results of each iteration to the files 'Output1.TXT', 'Output2.TXT', 'Output3.TXT', and so on.

Is there an easy way in Fortran to constuct filenames from the loop counter i?

回答1:

you can write to a unit, but you can also write to a string

program foo     character(len=1024) :: filename      write (filename, "(A5,I2)") "hello", 10      print *, trim(filename) end program 

Please note (this is the second trick I was talking about) that you can also build a format string programmatically.

program foo      character(len=1024) :: filename     character(len=1024) :: format_string     integer :: i      do i=1, 10         if (i 


回答2:

A much easier solution 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 


回答3:

Well here is a simple function which will return the left justified string version of an integer:

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

And here is a test code:

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 


回答4:

For a shorten version. If all the indices are smaller than 10, then use the following:

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

For a general version:

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 

That's all.



回答5:

I already showed this elsewhere on SO (How to use a variable in the format specifier statement? , not an exact duplicate IMHO), but I think it is worthwhile to place it here. It is possible to use the techniques from other answers for this question to make a simple function

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 

which you can use after without worrying about trimming and left-adjusting and without writing to a temporary variable:

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

It requires Fortran 2003 because of the allocatable string.



回答6:

I've tried @Alejandro and @user2361779 already but it gives me an unsatisfied result such as file 1.txt or file1 .txt instead of file1.txt. However i find the better 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)) ... 

Explanation:

e.g. set i = 10 and 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 

I think this is a simplest solution that give you a dynamical length filename without any legacy blank spaces from integer to string conversion process.



回答7:

To convert an integer to a string:

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 


回答8:

Here is my subroutine approach to this problem. it transforms an integer in the range 0 : 9999 as a character. For example, the INTEGER 123 is transformed into the character 0123. hope it helps.

P.S. - sorry for the comments; they make sense in Romanian :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=10.and.i=100.and.i=1000.and.i


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!