Схема лукавства читала-читала мимо EOF

Используя guile 1.8 или guile 2, следующий код читает EOF, казалось бы, на несколько дополнительных строк, а затем останавливается. Эффект, который это оказывает в более крупной программе, частью которой является извлечение, состоит в том, что, по-видимому, происходит повреждение ранее прочитанных данных. Я неправильно использую read-line или тестирую eof-объект?

(use-modules (ice-9 rdelim))

(define f
  (lambda (p)
    (let loop ((line (read-line p)))
      (format #t "line: ~a\n" line)
      (if (not (eof-object? (peek-char p)))
      (begin
        (let ((m (string-match "^[ \t]*#" line)))
          (if m
          (begin
              (format #t "comment: ~a\n" (match:string m))
              (loop (read-line p))
            )))
        (format #t "read next line\n")
        (loop (read-line p)))))))

(define main
  (lambda ()
    (let ((h (open-input-file "test")))
      (f h))))

Вот минимальный образец входного файла:

1
2
3
# comment line
4
5
1
2
3
# comment line
4
5
1
2
3
# comment line
4
5

Это должно быть больше, чем несколько строк, чтобы проблема могла проявиться. Извиняюсь за длину примера кода, но проблема возникает только тогда, когда код достигает такой степени сложности (хотя и небольшой).

1 ответ

Решение

Я предлагаю переписать процедуру, это не кажется правильным способом прочитать файл и перебрать его строки. Примерьте вот это:

(define (f)
  (let loop ((line (read-line)))
    (if (not (eof-object? line))
        (begin
          (format #t "line: ~a\n" line)
          (let ((m (string-match "^[ \t]*#" line)))
            (if m (format #t "comment: ~a\n" line)))
          (format #t "read next line\n")
          (loop (read-line))))))

(define (main)
  (with-input-from-file "test" f))

С вашим примером ввода, позвонив (main) выводит на консоль следующий вывод, который, как мы надеемся, соответствует ожидаемому:

line: 1
read next line
line: 2
read next line
line: 3
read next line
line: # comment line
comment: # comment line
read next line
line: 4
read next line
line: 5
read next line
line: 1
read next line
line: 2
read next line
line: 3
read next line
line: # comment line
comment: # comment line
read next line
line: 4
read next line
line: 5
read next line
line: 1
read next line
line: 2
read next line
line: 3
read next line
line: # comment line
comment: # comment line
read next line
line: 4
read next line
line: 5
read next line
Другие вопросы по тегам