在Fortran 90中将字符串转换为整数

时间:2014-06-05 23:14:55

标签: string integer fortran character fortran90

我知道IACHAR(s)在字符串s的第一个字符位置返回ASCII字符的代码,但我需要将整个字符串转换为整数。我也有一些字符串(大约30个字符串,每个字符串最多包含20个字符)。有没有办法将它们中的每一个转换为Fortran 90中的唯一整数?

2 个答案:

答案 0 :(得分:15)

您可以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

答案 1 :(得分:0)

您可以按照建议使用read()方法,也可以将faiNumber用于我在https://github.com/kevinhng86/faiNumber-Fortran编写的Fortran(faiNumber-Fortran)。 faiNumber-Fortran的运行速度比read()快约10倍(已在gfortran8的旧版,f95,f2003和f2018版本中进行了测试)。

此外,如果使用faiNumber-Fortran,则应防止使用无效字符串,例如“ 1 abc”,“ 125 7895”等。这些格式可以通过read()过程进行解析(已在gfortran8的旧版,f95,f2003和f2018版本中进行了测试)。 faiNumber会在其中通知您输入字符串无效。

对于版本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