我正在循环阅读stdin,并与一堆“ if”进行比较,以根据输入内容决定要做什么。
这是这段代码的简短片段:
CHARACTER (len= :), allocatable :: input
CHARACTER (len=4096) :: inbuffer ! frustrating but... well, fortran :3
DO
! get input
READ(*, '(a)') inbuffer ! because apparently you can't have allocation on read so you can't just read "input". meh.
input = TRIM(inbuffer)
CALL debug_log(input)
IF(input .EQ. 'uci') THEN
CALL debug_log(" printing uci info")
!isready
ELSE IF(input .EQ. 'isready') THEN
CALL debug_log(" isready -> readyok")
WRITE(*, '(a)') "readyok"
!ucinewgame
ELSE IF(input .EQ. 'ucinewgame') THEN
CALL debug_log("not implemented : reset board and start a new game")
!position
ELSE IF(input(1:8) .EQ. 'position') THEN
CALL debug_log("not implemented : set position")
!quit -> exit main loop
ELSE IF(input .EQ. 'quit') THEN
CALL debug_log(" quit command issued, exiting main loop")
EXIT
!non uci command
!nothing yet
!unknown command
ELSE
CALL debug_log(" ignoring invalid command")
END IF
end do
输入将期望输入类似“位置123 23415等...”的命令
如果我键入“ posi”,则表示这是预期的无效命令。
如果我键入“ position”,则表示它也没有按预期实现。
但是:
我的猜测是,即使输入只有4个字符,它也会读取8个字符,并且由于上一个命令是“ position”,因此它的位置为+位置= p
以下是一些日志来演示:
** opening debug file : 20181111 / 223418.127
223418.127 : Initializing Fortiche engine
223418.129 : Entering main loop
223420.859 : posi
223420.859 : ignoring invalid command
223426.467 : xxxxtion
223426.467 : ignoring invalid command
223430.498 : posi
223430.498 : not implemented : set position
223437.323 : xxxxxxxxx
223437.323 : ignoring invalid command
223439.418 : posi
223439.418 : ignoring invalid command
223443.979 : position
223443.979 : not implemented : set position
223447.122 : quit
223447.122 : quit command issued, exiting main loop
223447.122 : closing, bye
xxxxtion + posi =位置
这显然是错误的,但是我可以理解它是如何最终结束的。
我应该使用.EQ以外的其他名称吗? 当我打印输入时,显然不会打印输入+内存中留下的任何垃圾。但是在比较长度可能不同的字符串时会这样做。
我该怎么做才能解决此问题?
我什至没有开始进行核心解析,我已经遇到了问题。
我在Windows上使用GNU Fortran。
是的,它是UCI的通用国际象棋界面。
编辑:完整源代码:https://github.com/ker2x/fortiche(注释第107和108行的肮脏黑客以重现该问题)
答案 0 :(得分:4)
子字符串引用的开始和结束位置必须在字符串的范围内。
对于在子字符串引用input(1:8) .eq. 'position'
之前长度小于八的字符串,您不会采取任何措施。
如果输入的字符少于八个字符,则您的程序将不符合要求,则任何事情都可能发生,其中很合理的任何事情都包含您所看到的行为。
运行时调试选项可能有助于捕获此编程错误,具体取决于编译器的功能。