字符串提取数据的4种方法
本帖最后由 weixing1531 于 2024-6-16 13:36 编辑例如从字符串"SetColor(255,30,58)"提取255,30,58这三个整数
方法1、方法2为Fortran方法,利用read,index
方法3、方法4为C语言方法,利用函数sscanf,strtok
program main
use iso_c_binding
implicit none
interface
!void c_sscanf(const char *str,const char *ft,int *r,int *g,int *b)
subroutine c_sscanf(str,ft,r,g,b) bind(c) !封装c语言sscanf子程序
import::c_char,c_int
character(c_char),intent(in)::str(*),ft(*)
integer(c_int)::r,g,b
end subroutine
!void c_strtok(char *str,char *ft,int *num,char out[],int *len)
subroutine c_strtok(str,ft,num,out,len) bind(c) !封装c语言strtok子程序
import::c_char,c_int
character(c_char),intent(in)::str(*),ft(*)
integer(c_int)::num !子字符串个数
character(kind=c_char)::out(*) !子字符串拼接
integer(c_int)::len !字符串长度
end subroutine
end interface
integer::left,right !边界位置
integer(c_int)::r,g,b,lenth,num
character(100)::temp_str !用于占位
character(100)::out
character(:),allocatable::str,sep !被解析字符串 间隔符
!方法1
str="SetColor(255,30,58)" !被解析字符串
sep=str(13:13) !间隔符
write(*,"('被解析字符串:',a)")str
write(*,"('间隔符:[',a,']')")sep
read(str,"(a9,i3,a1,i2,a1,i2)")temp_str,r,temp_str,g,temp_str,b
write(*,"('方法1:',*(i0,1x))")r,g,b !缺点:i格式宽度必须固定
r=0;g=0;b=0 !置0
if(sep=="," .or. sep==" ")then !间隔符限制(" "或",")
!方法2
left=index(str,"(") !左边界位置
right=index(str,")") !右边界位置
read(str(left+1:right-1),*)r,g,b
write(*,"('方法2:',*(i0,1x))")r,g,b !缺点:间隔符限制(" "或",")
r=0;g=0;b=0 !置0
end if
!方法3
call c_sscanf(str//c_null_char,"SetColor(%d"//sep//"%d"//sep//"%d)"//c_null_char,r,g,b)
write(*,"('方法3:',*(i0,1x))")r,g,b !缺点:Fortran不支持可变形参,参数个数变化需修改c源代码和Fortran接口
r=0;g=0;b=0 !置0
!方法4
call c_strtok(str//c_null_char,"("//sep//")"//c_null_char,num,out,lenth) !方法1
write(*,"('元素个数:',i0,/'字符串长度:',i0)")num,lenth
write(*,"('字符串:',a)")out(1:lenth)
read(out(1:lenth),*)temp_str,r,g,b
write(*,"('方法4:',*(i0,1x))")r,g,b !较复杂
deallocate(str,sep)
read(*,*)
end program
页:
[1]