2013-10-31 60 views
3

我正在嘗試編寫一個小型實用程序,它可以將菜單條目列表作爲字符串(理想情況下,在子例程調用中明確定義),將這些字符串呈現爲編號選項,並要求用戶選擇一個。驗證的責任由調用例程決定。我的第一次嘗試,使用與數組初始化語句相同的方式定義的顯式字符串數組失敗,所以我嘗試了使用連續行發送帶有'marker'字符的單個顯式字符串的方法。將一組顯式字符串傳遞給Fortran子例程

下似乎gfortran 4.7.3工作在Cygwin下:

PROGRAM menutest 
IMPLICIT NONE 
INTEGER :: n 
CALL menu(n, 'This is option 1$& 
       Option Two$& 
       Option number three$') 
WRITE(*,*) 'You chose option ' ,n 
END PROGRAM menutest 

SUBROUTINE menu(n, entrylist) 
IMPLICIT NONE 
INTEGER :: n, i, nitems,pos1,pos2 
CHARACTER (LEN=*) :: entrylist 
! 
pos1 = 1 
pos2 = 1 
i=1 
! Loop over entries 
DO 
    entrylist = entrylist(pos1:) 
    pos2 = INDEX(entrylist,'$') 
    IF (pos2 == 0) THEN 
    EXIT 
    END IF 
    WRITE (*,'(A,I2,A,A)') '(',i,') ',entrylist(:pos2-1) 
    i = i+1 
    pos1 = pos2+1 
END DO 
WRITE(*,*) 'Choose an option from the menu' 
READ(*,*) n 
END SUBROUTINE menu 

不幸失敗使用Linux gfortran 4.5.x.我需要一種能夠在儘可能多的編譯器上儘可能多地運行儘可能多的F95編譯器並在儘可能多的平臺上可靠工作的解決方案。我希望能夠在我的程序中多次調用它,使用不同長度的不同長度的字符串列表。

有沒有人有更好的解決方案?

+0

在這裏的錯誤是,你正在修改這是作爲一個傳遞的字符串文字。你可以通過從不重新分配來解決這個問題,但是跟蹤開始/結束位置並且寫入.. entrylist(ipos1:ipos2).. – agentp

+0

這也違反了自由格式的行 - 字符上下文連續規則(續行在這種情況下,必須以「&」符號開頭)。 – IanH

+0

@ IanH很好。 FWIW gfortran表現得很好。省略繼續線上的前導空白。顯然,是否包含這些空白是不明確的。 – agentp

回答

2

你當然也可以發送一個字符串數組:

CALL menu(n, [character(20) :: 'This is option 1', & 
           'Option Two', & 
           'Option number three']) 
write(*,*) 'You chose option ' ,n 

contains 
    subroutine menu(n, entrylist) 
    CHARACTER(len=*),intent(in) :: entrylist(:) 
    integer, intent(out) :: n 
    integer i 
    do i=1,size(entrylist) 
     write(*,*) trim(entrylist(i)) 
    end do 
    read(*,*) n 
    end subroutine 

end 

數組構造的這種形式的Fortran 2003。如果你必須避免它,然後通過元素的正常分配建立數組。

strings(1) = 'This is option 1' 
strings(2) = 'Option Two' 
strings(3) = 'Option number three' 
call menu(n, strings) 

請注意,子程序需要一個明確的接口,因此它是這個簡短示例中的內部過程。您通常需要在全尺寸程序的模塊中使用它。

0

簡單的修復,不會修改這是作爲文字傳遞的字符串:

! entrylist = entrylist(pos1:) <-- get rid of this offending line 
    pos2 = pos1-1+INDEX(entrylist(pos1:),'$') 
    IF (pos2 == pos1-1) THEN 

     ... 

    WRITE (*,'(A,I2,A,A)') '(',i,') ',entrylist(pos1:pos2-1) 

與gfortran 4.x版測試

相關問題