IACHAR(s)
が文字列sの最初の文字位置にあるASCII文字のコードを返すことは知っていますが、文字列全体を整数に変換する必要があります。また、文字列の数が数個あります(約30文字列、それぞれが最大20文字で構成されます)。Fortran90で各文字列を一意の整数に変換する方法はありますか?
文字列を整数変数にread
することができます。
module str2int_mod
contains
elemental subroutine str2int(str,int,stat)
implicit none
! Arguments
character(len=*),intent(in) :: str
integer,intent(out) :: int
integer,intent(out) :: stat
read(str,*,iostat=stat) int
end subroutine str2int
end module
program test
use str2int_mod
character(len=20) :: str(3)
integer :: int(3), stat(3)
str(1) = '123' ! Valid integer
str(2) = '-1' ! Also valid
str(3) = 'one' ! invalid
call str2int(str,int,stat)
do i=1,3
if ( stat(i) == 0 ) then
print *,i,int(i)
else
print *,'Conversion of string ',i,' failed!'
endif
enddo
end program
提案されているようにread()メソッドを使用するか、 https://github.com/kevinhng86/faiNumber-Fortran で私が作成したFortran(faiNumber-Fortran)のfaiNumberを使用できます。 faiNumber-Fortranはread()よりも約10倍高速に動作しました(ビルドバージョンlegacy、f95、f2003、およびf2018を備えたgfortran8でテスト済み)。
また、faiNumber-Fortranを使用すると、「1 abc」、「1257895」などの無効な文字列から保護されます。これらの形式は、read()プロシージャ(ビルドバージョンlegacy、f95、f2003、およびf2018を使用したgfortran8でテスト済み)によって解析可能です。ここで、faiNumberは、入力文字列が無効であることを通知します。
バージョン1の場合、2つのバージョンがあります。1つは純粋なプロシージャで使用するためのもので、そのうちの1つは、不純なプロシージャでのみ使用できるバージョンよりもわずかに低速です。
FaiNumber-Fortranでは、文字列の開始位置と終了位置を選択することもできます。以下は、あなたができることの小さな例です。例以外にもたくさんあります。それにもかかわらず、私はコードを非常に徹底的に文書化しました(私は願っています)。この例は、すべて純粋なプロシージャライブラリとしてビルドされたバージョン用です。
program example
! For 64/128, use fnDecimalUtil64/fnDecimalUtil128.
! To use procedures of 64/128, The right module have to be called.
use fnDecimalUtil
implicit none
! For 64/128, integer kind are k_int64/k_int128.
integer(k_int32) :: resultValue, startpos, endpos
! Where there is an error code return, it will always be an int32 value.
integer(k_int32) :: errorInt
logical :: errorLogical
! For 64/128, call decToInt64/decToInt128.
call decToInt32("123", resultValue, errorLogical)
if ( errorLogical .eqv. .FALSE. ) then
print *, resultValue
else
print *, "There was an error during parsing."
end if
startpos = 13
endpos = 17
call decToInt32(" This here($12345)can be parse with start and end", &
resultValue, errorLogical, startpos, endpos)
if ( errorLogical .eqv. .FALSE. ) then
print *, resultValue
else
print *, "There was an error during parsing."
end if
! This procedure below is where you need to know what was wrong
! during parsing the input string.
!
! This may run slower if the strings are long. The TrueError procedure
! has exactly the same feature as the normal one, they are just
! different by how errors are handled.
!
! Empty string will be checked first then error 5.
!
! If error 5 is encountered, nothing else will be check. For error
! 5, startpos will be checked first before endpos.
!
! For 64/128, call decToInt64TrueError/decToInt128TrueError
startpos = 12
call decToInt32TrueError(" line 24: 1278421", resultValue, errorInt, startpos) ! startpos can be used without endpos,
if ( errorInt == 0 ) then
print *, resultValue
else if ( errorInt == 1 ) then
print *, "The input string was empty."
else if ( errorInt == 2 ) then
print *, "The input string contained an invalid decimal integer."
else if ( errorInt == 3 ) then
print *, "The input string contained a value that is smaller than the minimum value of the data type."
else if ( errorInt == 4 ) then
print *, "The input string contained a value that is larger than the maximum value of the data type."
else if ( errorInt == 5 ) then
print *, "It was either startpos > length, endpos < startpos, or endpos < 1."
end if
end program example