特点:
1. 可提供对 ini 配置文件中的 整型,字符串,浮点数,双精度进行读取。
2. 无需按文件顺序
3. Section段,Key值区分大小写
4. 可自定义逻辑型的真假字符串,比如 "T|F" , "1|0" , "YES|NO"
5. 可设置默认值,当 Key 值在 ini 文件中不存在或设置错误时,变量赋为默认值。
例:如下的ini文件
[config] QQGroup = 2338021 Website = www.fcode.cn [Test] Age = 29 Weight = 31.415926 Name = 臭石头雪球 Home = /home/gao/ Married = Yes
Module ini_file_mod !// INI file read module in Fortran95 !// Author: Gao , You may write to E-mail: gao@fcode.cn !// version 1.4 @ 2015.11.6 !// usage: !// use ini_file_mod !// integer iErr !// type( CLASS_INI ) :: ObjName !// iErr = ObjName%Conn( "filename.ini" ) !// iErr = ObjName%Section( "SectionName" ) !// iErr = ObjName%Get( "IntegerKey" , var_int ) !// iErr = ObjName%Get( "RealKey" , var_real ) !// iErr = ObjName%Get( "RealKey" , var_double ) !// iErr = ObjName%Get( "StringKey" , var_char ) !// iErr = ObjName%Get( "IntegerKey" , var_int , int_def ) !// iErr = ObjName%Get( "LogicalKey" , var_logical , "T|F" ) !// call ObjName%Disconn() Implicit None Private Integer , parameter , private :: DP = Selected_Real_Kind( p = 9 ) Type , public :: CLASS_INI character( len = 64 ) , Private :: SectionName = '' Integer , Private :: fileUnit = -1 contains Procedure , private :: ReadINI_Int Procedure , private :: ReadINI_String Procedure , private :: ReadINI_Real Procedure , private :: ReadINI_Double Procedure , private :: ReadINI_Logic Generic :: Get => ReadINI_Int,ReadINI_String,ReadINI_Real,ReadINI_Double,ReadINI_Logic Procedure :: Conn Procedure :: Section Procedure :: DisConn End Type CLASS_INI contains Integer Function Conn( this , INIFileName ) Class( CLASS_INI ) :: this Character( Len = * ) , Intent( In ) :: INIFileName integer :: iErr Conn = 0 Open( NewUnit = this%fileUnit , File=INIFileName , status='old' , action='Read' , IoStat=iErr ) If (iErr/=0) return Conn = 1 End Function Conn Subroutine DisConn( this ) Class( CLASS_INI ) :: this Close( this%fileUnit ) End Subroutine DisConn Integer Function Section( this , sectionName ) Class( CLASS_INI ) :: this Character( Len = * ) , Intent(In) :: sectionName character(len=512) :: cRead integer :: iErr Section = 0 if ( CheckParNameValidity(Trim(sectionName)) ) return Rewind( this%fileUnit ) Do Read( this%fileUnit , '(a512)' , ioStat=iErr ) cRead if( iErr/=0 ) exit cRead = adjustl(cRead) If ( index( cRead , '['//trim(sectionName)//']' ) == 1 ) then this%SectionName = sectionName Section = 1 exit End If End Do End Function Section Integer Function ReadINI_String( this , parName , value , defaultValue ) result( iRes ) Class( CLASS_INI ) :: this Character( Len = * ) , Intent(In) :: parName Character( len = * ) , Intent(OUT) :: Value Character( len = * ) , Intent(In) , Optional :: defaultValue character(len=512) :: cRead integer :: iErr , iRead , k Logical :: bOK iRes = 0 iRead = 0 bOK = .false. Do Read( this%fileUnit , '(a512)' , ioStat=iErr ) cRead if ( iErr /= 0 ) exit cRead = adjustl(cRead) iRead = iRead + 1 If ( cRead(1:1)== '[' ) exit k = index( cRead , '=' ) If ( k < 2 ) cycle If ( trim(cRead(1:k-1)) == parName ) then value = adjustl(cRead(k+1:)) bOK = .true. exit End If End Do Do k = 1 , iRead BackSpace( this%fileUnit ) End Do If ( .Not.bOK .and. Present(defaultValue)) then value = defaultValue iRes = 1 Else If ( bOK ) then iRes = 1 End If End Function ReadINI_String Integer Function ReadINI_Int( this , parName , value , defaultValue ) result( iRes ) Class( CLASS_INI ) :: this Character( Len = * ) ,Intent(In) :: parName Integer , Intent(In) , Optional :: defaultValue Integer , Intent(OUT) :: Value integer :: i , iErr Character( len = 16 ) :: c iRes = 0 if ( CheckParNameValidity( parName ) ) return i = this%Get( parName , c ) If ( i==0 .and. Present(defaultValue)) then value = defaultValue iRes = 1 Else If ( i==1 ) then Read( c , * , ioStat = iErr ) value if ( iErr==0 ) iRes = 1 End If End Function ReadINI_Int Integer Function ReadINI_Real( this , parName , value , defaultValue ) result( iRes ) Class( CLASS_INI ) :: this Character( Len = * ) ,Intent(In) :: parName Real , Intent(In) , Optional :: defaultValue Real , Intent(OUT) :: Value integer :: i , iErr Character( len = 16 ) :: c iRes = 0 if ( CheckParNameValidity( parName ) ) return i = this%Get( parName , c ) If ( i==0 .and. Present(defaultValue)) then value = defaultValue iRes = 1 Else If ( i==1 ) then Read( c , * , ioStat = iErr ) value if ( iErr==0 ) iRes = 1 End If End Function ReadINI_Real Integer Function ReadINI_Double( this , parName , value , defaultValue ) result( iRes ) Class( CLASS_INI ) :: this Character( Len = * ) ,Intent(In) :: parName Real(Kind=DP) , Intent(In) , Optional :: defaultValue Real(Kind=DP) , Intent(OUT) :: Value integer :: i , iErr Character( len = 16 ) :: c iRes = 0 if ( CheckParNameValidity( parName ) ) return i = this%Get( parName , c ) If ( i==0 .and. Present(defaultValue)) then value = defaultValue iRes = 1 Else If ( i==1 ) then Read( c , * , ioStat = iErr ) value if ( iErr==0 ) iRes = 1 End If End Function ReadINI_Double Integer Function ReadINI_Logic( this , parName , value , TFStr ) result( iRes ) Class( CLASS_INI ) :: this Character( Len = * ) , Intent(In) :: parName Character( Len = * ) , Intent(In) , Optional :: TFStr Logical , Intent(Out) :: Value character(Len=20) :: RChar character(Len=41) :: TFChar integer :: Separator = 0 iRes = 0 if ( CheckParNameValidity( parName ) ) return TFChar='1|0' If ( Present(TFStr) ) TFChar=TFStr Separator = Index( TFChar , '|' ) If ((Separator<=1).or.(Separator==Len_Trim(TFChar))) return If ( this%Get( parName , RChar ) == 0 ) return If ( Trim(RChar) == TFChar(1:Separator-1) ) then Value = .True. iRes = 1 Else If (Trim(RChar) == TFChar(Separator+1:Len_Trim(TFChar)) ) then Value = .False. iRes = 1 End If End Function ReadINI_Logic Logical Function CheckParNameValidity(ParName) Character( Len = * ) , Intent(In) :: ParName CheckParNameValidity = ( Scan(ParName,'[]/!@#$%&() =}{";:\|.><') /= 0 ) End Function CheckParNameValidity End Module ini_file_mod Program www_fcode_cn use ini_file_mod Implicit None integer :: iErr , i real :: r real(kind=kind(0.d0)) :: rr Character( Len = 50 ) :: c logical :: l Type( CLASS_INI ) :: MyINI iErr = MyINI%Conn( "fcode.ini" ) !// 连接ini文件 iErr = MyINI%Section( "Test" ) !// 读取 Test 部分 iErr = MyINI%Get( "Home" , c ) write(*,*) '家路径:',Trim(c) iErr = MyINI%Get( "Name" , c ) write(*,*) '姓名:',Trim(c) iErr = MyINI%Get( "Weight" , r ) write(*,*) '体重:',r iErr = MyINI%Get( "Weight" , rr ) write(*,*) '体重(双精度):',rr iErr = MyINI%Get( "Age" , i ) write(*,*) '年龄:',i iErr = MyINI%Get( "Married" , l , "Yes|No" ) !// "T"表示真,"F"表示假 write(*,*) '是否已婚:',l iErr = MyINI%Get( "不存在" , i , 30 ) write(*,*) '不存在的整型:',i !// 不存在值则以默认值为准 iErr = MyINI%Section( "config" ) iErr = MyINI%Get( "Website" , c ) write(*,*) '网站:',Trim(c) iErr = MyINI%Get( "QQGroup" , i ) write(*,*) 'QQ群:',i call MyINI%DisConn() !// 关闭 ini 文件 End Program www_fcode_cn