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

发布于 2024-08-02 04:08:30 字数 287 浏览 5 评论 0原文

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

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

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

Fortran 中有没有一种简单的方法可以从循环计数器 i 构建文件名?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

甚是思念 2024-08-09 04:08:30

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

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

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
戴着白色围巾的女孩 2024-08-09 04:08:30

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

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

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
゛时过境迁 2024-08-09 04:08:30

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

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

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
难忘№最初的完美 2024-08-09 04:08:30

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

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.

千年*琉璃梦 2024-08-09 04:08:30

对于缩短版本。
如果所有索引都小于 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

仅此而已。

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.

双马尾 2024-08-09 04:08:30

我已经尝试过 @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))
...

解释:

例如 set 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'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.

一生独一 2024-08-09 04:08:30

请尝试以下操作:

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

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

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.

不再让梦枯萎 2024-08-09 04:08:30

这是在循环中为不同参数写入文件的答案

program sinnx_diff_n
implicit none
integer :: n, xloop
real*8  :: x,y
character(len=40)  :: nchar

do n=1,4
    
    write(nchar,6)n
    6 format(I5)    

    open (8,file="data-x-vs-y-n="//trim(adjustl(nchar))//"-values.dat", status="replace",action="write")   ! this line is storing data for each n value.

    do xloop=-40,40
        x=real(xloop)/10.0d0
        y=sin(n*x)            ! writing y = sin(x) for a single n value
        write(8,34)x,y
        34 format(2x, 10f16.8)  ! this will accommodate 10 columns of real values with gap of 2 spaces between each data column.
    end do            ! end of x loop

end do  ! end of different n loop   
    
end program

Here is the answer for writing files for different parameters in a loop

program sinnx_diff_n
implicit none
integer :: n, xloop
real*8  :: x,y
character(len=40)  :: nchar

do n=1,4
    
    write(nchar,6)n
    6 format(I5)    

    open (8,file="data-x-vs-y-n="//trim(adjustl(nchar))//"-values.dat", status="replace",action="write")   ! this line is storing data for each n value.

    do xloop=-40,40
        x=real(xloop)/10.0d0
        y=sin(n*x)            ! writing y = sin(x) for a single n value
        write(8,34)x,y
        34 format(2x, 10f16.8)  ! this will accommodate 10 columns of real values with gap of 2 spaces between each data column.
    end do            ! end of x loop

end do  ! end of different n loop   
    
end program
会发光的星星闪亮亮i 2024-08-09 04:08:30

要将整数转换为字符串:

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

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
久夏青 2024-08-09 04:08:30

这是我解决这个问题的子程序方法。 它将 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

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<=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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文