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
Convert integers to strings to create output filenames at run time
提问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.txt
or file1 .txt
instead of file1.txt
. However i find the better solution:
我已经尝试过@Alejandro 和@user2361779,但它给了我一个不满意的结果,例如file 1.txt
或file1 .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 = 10
and write(char_i, '(I5)') i
例如设置i = 10
和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.
我认为这是一个最简单的解决方案,它为您提供动态长度的文件名,而没有任何从整数到字符串转换过程的遗留空格。
回答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