2013-10-31 62 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版测试

相关问题