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

プログラムでフォーマット文字列を作成することもできることに注意してください (これは私が話していた 2 番目のトリックです)。

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

はるかに簡単なソリューション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
于 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 の他の場所で示しました ( How to use a variable in the format specifier statement?、正確な複製 IMHO ではありません) が、ここに配置する価値があると思います。この質問に対する他の回答の手法を使用して、単純な関数を作成することができます

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.txtます。しかし、私はより良い解決策を見つけます:file1 .txtfile1.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 に答える
-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 に答える