web-dev-qa-db-ja.com

整数を文字列に変換して、実行時に出力ファイル名を作成します

結果をファイルに保存するFortranのプログラムがあります。現時点では、次を使用してファイルを開きます

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

ただし、ループを実行して、各反復の結果をファイル'Output1.TXT''Output2.TXT''Output3.TXT'、 等々。

Fortranでループカウンターiからファイル名を構成する簡単な方法はありますか?

42
Alasdair

ユニットに書き込むことができますが、文字列に書き込むこともできます

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
48
Stefano Borini

はるかに簡単なソリューション.

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
18
Alejandro

整数の左揃えの文字列バージョンを返す単純な関数は次のとおりです。

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
9
cyberthanasis

私はすでにこれをSO( フォーマット指定子ステートメントで変数を使用する方法? 、正確な複製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が必要です。

6
Vladimir F

短縮版の場合。すべてのインデックスが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

それで全部です。

2
kayneo

以下を試してください:

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

「...」は、目的に適した他のコードを意味します。

0
Michael

私はすでに@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))
...
_

説明:

例えば_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
_

これは、整数から文字列への変換プロセスから従来の空白スペースなしで、動的な長さのファイル名を提供する最も簡単なソリューションだと思います。

0
fronthem