考虑这个程序,
PROGRAM FOO
CHARACTER(LEN=25) :: INP
CHARACTER(LEN=50) :: C
INP = 'The quick brown fox ...'
READ (INP, '(A)') C
WRITE (*, '(''['', A, '']'')') C
STOP
END
输出52个字符,
[The quick brown fox ... ]
我希望它能输出放入READ
数组的C
语句,而不是C
缓冲区中的所有额外空格。
在上述情况下,我希望输出为[The quick brown fox ...]
,或者(A5)
用作(A)
语句的格式而不是READ
,那么我希望输出为[The q]
我希望看到READ
语句
我该怎么做?
更新
由于看起来这是不可能的直接,是否可以用一些深奥的字符(即~
)预先填充字符变量,然后用READ
语句覆盖?
到目前为止,我的尝试似乎被Fortran READ
声明所覆盖,即
PROGRAM FOO
CHARACTER(LEN=50) :: INP
CHARACTER(LEN=50) :: C
C = REPEAT('~', 50)
INP = 'The quick brown fox ...'
READ (INP, '(TR50, A1)') C
WRITE (*, '(''['', A, '']'')') C
STOP
END
! Outputs [<50 blanks>] rather than [<50 tildas>] or [ <49 tildas>]
! which would tell me if Fortran always reads a number of characters
! equal to the specified width or never reads any characters beyond
! the end of the record
! n.b. I am interested in actual output for individual platforms,
! not what the spec says
答案 0 :(得分:4)
普通的Fortran字符串是固定长度的,并在末尾用空格填充。因此,您无法通过稍后检查字符串来判断输入的时间长度,或者判断是否已读取尾随空白或填充以扩展字符串。这是非常基础的。它与其他语言不同,例如使用终结符。也许它是原始的,但另一方面缓冲区溢出是不可能的。
现在有四种方法可以在Fortran中使用可变长度字符串。多年来,ISO_VARYING_STRING模块一直有ISO标准。这个模块有开源实现。你“调用GET”来读取一个字符串并“调用PUT_LINE”来编写它。虽然这个模块不受欢迎,但我发现它运作良好。
最近的替代方案(Fortran 2003的一个功能)是可分配的缩放器。对于可变长度字符串的使用,我不那么熟悉了,直到最近它还得到了少数编译器的支持。在Web上,声明的语法是:
CHARACTER(LEN=:), ALLOCATABLE :: S
答案 1 :(得分:1)
如果您需要消除字符串末尾的空格,可以使用trim
函数:
program foo
character(len=24) :: inp
character(len=50) :: c
inp = 'The quick brown fox ...'
read (inp, '(A5)') c
write (*, '(''['',A,'']'')') trim(c)
read (inp, '(A)') c
write (*, '(''['',A,'']'')') trim(c)
end program foo
打印
[The q]
[The quick brown fox ...]
修改:如评论中所述,如果您要截断字符串中所读取的字符数,并且知道它的长度(例如,在A5中键入格式字符串)您只需选择子字符串:
read(inp, '(A5)') c
write (*, '(''['',A,'']'')') c(1:5)
适用于您希望打印空间的A4的情况。如果希望长度变化,可以存储格式字符串。在长度为4的情况下,这就像
character(len=10) :: fmt
fmt = '(A4)'
read(inp, fmt) c
然后,您可以使用整数变量构造fmt
,并使用相同的整数变量作为字符串切片中的索引。
答案 2 :(得分:1)
我遇到了完全相同的问题:我必须从文件中读取行,这些行有时会留下需要保留的空白以保持程序运行,这需要某些空白。
发现使用ISO_VARYING_STRING扩展可以正常运行,但速度上对我简单且效率低下的解决方案没有任何好处:
subroutine stringread(rcache,l)
implicit none
integer :: i,l, ierr
character(80) :: rcache
l=0
do i=1,81
read(20,'(A1)',advance='NO',iostat=ierr) rcache(i:i)
if (ierr.ne.0) exit
l=i
end do
write(30, '(A)') rcache(1:l)
end subroutine stringread
只需将char中的文件char行读入字符串,直到出现错误(行尾)。同时读取的字符数用l计算,所以我可以用rcache(1:l)输出我读到的内容。
与使用ISO_VARYING_STRING的优雅解决方案相比,该解决方案看起来可能看起来非常难看,但令人惊讶的是,对于大文件而言没有速度劣势。
答案 3 :(得分:0)
保留预期尾随空白的可能解决方案是将字符串与nul字符连接起来:
PROGRAM FOO
CHARACTER(LEN=25) :: INP
CHARACTER(LEN=50) :: C
INP = 'The quick brown fox ...'//CHAR(0)
READ (INP, '(A)') C
I=1
DO
IF (I.EQ.LEN(C).OR.C(I:I).EQ.CHAR(0)) EXIT
I=I+1
ENDDO
WRITE (*, '(''['', A, '']'')') C(1:I)
STOP
END