2017-05-26 28 views
1

我遇到了以下問題: 數據文件中有「n」行,但這不是問題,因爲我能夠讀取對我而言很有趣的特定行。但是,我應該只是閱讀並保存這一行的一個片段(一個值)。 例如,該行被寫入文件中: Resisting Moment = 2779.94 kN-m如何讀取Fortran中的數據文件中一行的一小段(值)?

然後,我必須閱讀並保存2779.94。也許,我可以通過閱讀「=」直到行尾,然後刪除最後5個字符。但是,我不知道是否有可能或如何做到這一點。有誰知道嗎?

該值的字符數可能會改變(例如,Resisting Moment = 27790.945 kN-m)。因此,我無法確定讀取結束的位置,我只能鎖定不會發生變化的起始點(在值之前)。

+2

你到目前爲止有什麼?我(和我懷疑其他人)不願意從方方面面教你Fortran,但很樂意幫助完成事務。 –

回答

1

此外,在@agentp和@Franz的解決方案之間的某處...

subroutine readrhs(line, val) 
    implicit none 
    character(*), intent(in) :: line 
    real,   intent(out) :: val 
    integer :: n 
    n = index(line, '=') 
    read(line(n+1 :), *) val 
end 

program main 
    implicit none 
    character(100) :: line 
    real :: val 

    line = "resisting moment = 12312.9 kN-m" 
    call readrhs(line, val) 
    print *, "moment = ", val 

    line = "force = 777.4 N" 
    call readrhs(line, val) 
    print *, "force = ", val 
end 
2

爲了支持你的格式,可能Fortran編輯描述符不夠用,你需要編寫一個專門用於 你的案例的解析器。如果典型的文件輸入是

resisting moment = 12312.9 kN-m 
force = 777.4 N 

一個可能的程序,其可以讀取它是:

subroutine split_string(instring, string1, string2, delimiter) 
    character(*), intent(inout) :: instring 
    character(*), intent(in) :: delimiter 
    character(*), intent(out):: string1, string2 
    integer :: ind 
    instring = trim(instring) 
    ind  = scan(instring, delimiter) 
    string1 = instring(1:ind-1) 
    string2 = instring(ind+1:) 
end subroutine split_string 

real function parsed_read(file_unit) 
    integer, intent(in) :: file_unit 
    character(128) :: str, str1, str2, str3, str4 
    read(file_unit,'(A)') str 
    str = trim(adjustl(str)) 
    call split_string(str, str1, str2, "=") 
    str2 = trim(adjustl(str2)) 
    call split_string(str2, str3, str4, " ") 
    str3 = trim(adjustl(str3)) 
    read(str3,'(F20.8)') parsed_read 
endfunction parsed_read 

program for 
    real :: resisting_moment, force 
    ! Read line by line and parse according to parsed_read function 
    open(unit=1,file='inp.dat') 
    resisting_moment = parsed_read(1) 
    force   = parsed_read(1) 
    close(1) 
    print*,'resisting_moment: ',resisting_moment 
    print*,'force: ',force 
endprogram for 

功能parsed_read由「=」分割線,然後通過「」 和提取從真實值從字符串本身讀取得到的字符串 (在Fortran中,在此上下文中稱爲內部文件 )。該功能需要根據您的具體格式調整爲 。

另一種方法是使用Fortran名單。 Fortran名單允許輕鬆管理參數(例如https://software.intel.com/en-us/node/679582) 的I/O,並具有許多已實施的有用功能。 將變量定義爲屬於名稱列表 之後,您可以使用單個讀取指令讀取它們(或它們的子集)。 如果您的輸入文件使用名稱列表格式,例如

&mynamelist 
resisting_moment = 12312.9, ! kN-m 
force = 777.4 ! N 
/

一個簡單的程序讀取它可以

program for 
    real :: resisting_moment, force 
    namelist /mynamelist/resisting_moment, force 
    ! Read namelist 
    open(unit=1,file='inp_nl.dat') 
    read(1, mynamelist) 
    close(1) 
    print*,'resisting_moment: ',resisting_moment 
    print*,'force: ',force 
endprogram for 
1
character (len = 20), dimension (5) :: words 
real::value 
... 
read(unit,*)words 
read(words(4),*)value 

小心不要嘗試讀取更多的「話」不是有就行了,例如,對於力(從@franz例如)你應該做

read(unit,*)words(:4) 
相關問題