string 将整数转换为字符串以在运行时创建输出文件名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1262695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 00:30:52  来源:igfitidea点击:

Convert integers to strings to create output filenames at run time

stringintegerfortran

提问by Alasdair

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

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

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.

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

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

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

回答by Stefano Borini

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 < 10) then
            format_string = "(A5,I1)"
        else
            format_string = "(A5,I2)"
        endif

        write (filename,format_string) "hello", i
        print *, trim(filename)
    enddo

end program

回答by Alejandro

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

回答by cyberthanasis

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

回答by Vladimir F

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

我已经在 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

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.

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

回答by kayneo

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

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

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.

就这样。

回答by fronthem

I've tried @Alejandro and @user2361779 already but it gives me an unsatisfied result such as file 1.txtor file1 .txtinstead of file1.txt. However i find the better solution:

我已经尝试过@Alejandro 和@user2361779,但它给了我一个不满意的结果,例如file 1.txtfile1 .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))
...

Explanation:

解释:

e.g. set i = 10and write(char_i, '(I5)') 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

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.

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

回答by Michael

Try the following:

请尝试以下操作:

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

Where "..." means other appropriate code for your purpose.

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

回答by Abankik

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

回答by unoptimizer

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.

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

P.S. - sorry for the comments; they make sense in Romanian :P

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