string 在 Fortran 90 中将字符串转换为整数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24071722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting a string to an integer in Fortran 90
提问by user3504976
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?
我知道IACHAR(s)
在字符串 s 的第一个字符位置返回 ASCII 字符的代码,但我需要将整个字符串转换为整数。我还有一些字符串(大约 30 个字符串,每个字符串最多包含 20 个字符)。有没有办法在 Fortran 90 中将它们中的每一个都转换为唯一的整数?
回答by Alexander Vogt
You can read
a string into an integer variable:
您可以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
回答by Kevin Ng
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).
您可以按照建议使用 read() 方法,也可以将 faiNumber 用于 Fortran(faiNumber-Fortran),这是我在https://github.com/kevinhng86/faiNumber-Fortran 上编写的。faiNumber-Fortran 的运行速度比 read() 快约 10 倍(使用 gfortran8 测试,构建版本为旧版、f95、f2003 和 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.
此外,如果您使用 faiNumber-Fortran,您可以防范无效字符串,例如“1 abc”、“125 7895”等。这些格式可通过 read() 过程进行解析(使用 gfortran8 与构建版本旧版、f95、f2003 和 f2018 进行测试)。其中 faiNumber 会通知您输入的字符串无效。
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.
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(345)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