[英]Problem with Fortran substring comparison of different length
我正在循環讀取 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”,則表示它是預期的無效命令。
如果我輸入“位置”,它表示它也沒有按預期實現。
但是:
我的猜測是,即使輸入只有 4 個字符,它也會讀取 8 個字符,並且由於上一個命令是“位置”,它使位置 + tion = 位置
下面是一些日志來演示:
** 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 行的臟黑客以重現問題)
子字符串引用需要具有在字符串限制內的開始和結束位置。
在子字符串引用input(1:8) .eq. 'position'
之前,您不會防御長度小於 8 的字符串input(1:8) .eq. 'position'
input(1:8) .eq. 'position'
。
如果輸入少於八個字符,則您的程序不符合標准,然后任何事情都可能發生,其中任何事情都非常合理地包括您看到的行為。
運行時調試選項可能有助於捕獲此編程錯誤,具體取決於編譯器的功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.