Reputation: 151
I know that IACHAR(s)
returns the code for the ASCII character in the first character position of the string s, but I need to convert the entire string to an integer. I also have a few number of strings (around 30 strings, each consists of at most 20 characters). Is there any way to convert each one of them to a unique integer in Fortran 90?
Upvotes: 14
Views: 36722
Reputation: 2174
You can use the read() method as suggested, or you could use faiNumber for Fortran(faiNumber-Fortran) that was written by me at https://github.com/kevinhng86/faiNumber-Fortran. faiNumber-Fortran operated about 10x faster than read()(tested with gfortran8 with build version legacy, f95, f2003, and f2018).
Also, if you use faiNumber-Fortran, you are guarded against invalid string such as "1 abc", "125 7895", and so on. Those formats are parsable by the read() procedure(tested with gfortran8 with build version legacy, f95, f2003, and f2018). Where faiNumber will notify you that the input string is invalid.
For version one you get two versions, one to use with pure procedures, of which slightly slower than the version that can only be used by impure procedures.
FaiNumber-Fortran also let you choose where to start and end in your string. This below is a small example of what you can do. There is a lot more than the example. Nonetheless, I documented the code very thoroughly(I hope). The example is for the version that built as an all pure procedures library.
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
Upvotes: 0
Reputation: 18098
You can read
a string into an integer variable:
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
Upvotes: 18