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

13

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


1
将整个字符串转换为ASCII或格式化数字?“123”是否应该结果为整数123?如果是,请参见https://dev59.com/fXM_5IYBdhLWcg3wt1g0和http://stackoverflow.com/questions/13316378/fortran-integer-to-string-example。 - Vladimir F Героям слава
请参考以下两个链接:http://stackoverflow.com/questions/21370190/extract-integers-from-string-in-fortran 和 https://dev59.com/KHbZa4cB1Zd3GeqPKNGa。这些链接提供了有关Fortran中从字符串中提取整数和读取混合字符串和数字数据的信息。 - M. S. B.
2个回答

17

您可以将一个字符串读入一个整数变量中: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

13
read(str,*,iostat=stat) int 表示读取一个字符串 str 并将其转换为整数类型的值,如果读取失败,则将状态码存储在变量 stat 中。这是其他像我一样搜索同样内容时需要关注的重要部分。感谢Alex。以下是一些其他示例:http://www.eng-tips.com/viewthread.cfm?qid=4337 和 http://vikas-ke-funde.blogspot.com/2010/06/int2str-and-str2num-in-fortran-how.html。 - user3407196

0
您可以使用建议的read()方法,或者您可以使用我在https://github.com/kevinhng86/faiNumber-Fortran上编写的faiNumber for Fortran(faiNumber-Fortran)。faiNumber-Fortran的运行速度比read()快约10倍(使用gfortran8进行测试,版本为legacy、f95、f2003和f2018)。
此外,如果您使用faiNumber-Fortran,您将受到保护,以防止无效字符串,例如"1 abc"、"125 7895"等。这些格式可以通过read()过程进行解析(使用gfortran8进行测试,版本为legacy、f95、f2003和f2018)。而faiNumber会通知您输入字符串无效。
对于第一个版本,您将获得两个版本,一个用于纯过程,稍微慢一些,另一个只能由不纯过程使用。

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

3
您应该披露您是所述库的作者。另外,提供一次转换过程的调用示例比仅有此产品广告更有价值。 - Vladimir F Героям слава

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接