Проблема со сравнением подстрок Фортрана разной длины - PullRequest
0 голосов
/ 12 ноября 2018

Я читаю stdin в цикле и провожу некоторое сравнение со связкой «если», чтобы решить, что делать в соответствии с вводом.

Вот сокращенный фрагмент кода:

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", он скажет, что он тоже не реализован должным образом.

Однако :

  • Если я наберу "положение": я не осуществлюсь
  • Далее следует «posi»: вместо «недопустимая команда» написано «не реализовано»

Я предполагаю, что он читает 8 символов, даже если ввод только 4, и, поскольку предыдущая команда была "position", он делает позицию + position

Вот журнал для демонстрации:

** 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.? Когда я печатаю ввод, он явно не печатает ввод + любой мусор, оставленный в памяти. Но это происходит при сравнении строки, возможно, другой длины.

Что я могу сделать, чтобы решить эту проблему?

Я даже не начал хардкорный разбор, и у меня уже есть проблема.

Я использую GNU Fortran в Windows.

Да, это UCI как универсальный шахматный интерфейс.

РЕДАКТИРОВАТЬ: Полный исходный код: https://github.com/ker2x/fortiche (прокомментируйте грязный хак в строке 107 и 108, чтобы воспроизвести проблему)

1 Ответ

0 голосов
/ 12 ноября 2018

Ссылки на подстроки должны иметь начальную и конечную позиции, которые находятся в пределах строки.

Вы не защищаетесь от строки длиной менее восьми до ссылки на подстроку input(1:8) .eq. 'position'.

Если ввод короче восьми символов, ваша программа не соответствует,Затем может произойти все, что угодно, в том числе поведение, которое вы видите.

Параметры отладки во время выполнения могут помочь отловить эту ошибку программирования, в зависимости от возможностей вашего компилятора.

...