Converting a string to an integer in Fortran 90

后端 未结 2 1583
遇见更好的自我
遇见更好的自我 2020-12-11 15:46

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 in

相关标签:
2条回答
  • 2020-12-11 16:15

    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
    
    0 讨论(0)
  • 2020-12-11 16:25

    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
    
    0 讨论(0)
提交回复
热议问题