2017-01-24 7 views
0

Я пытаюсь прочитать и написать матрицу из файла «data.txt». Матрица представляет собой списки со строками внутри них. Когда я пишу, я хочу написать с начала переопределение данных. В основном я удаляю файл каждый раз. Мне нужно более полное решение. Основная проблема заключается в том, что после нескольких чтений и корней файла развращает.Чтение и запись из файла в схеме

системная ошибка: доступ запрещен; ERRNO = 5

Мой код:

;reading file returning matix of strings 
(define (file-reader file-name) 
    (define pointer (open-input-file file-name)) 
    (define (helper line) 
    (cond 
     ((equal? line eof) '()) 
     ((cons (list line) (helper (read-line pointer)))))) 
    (list-matr (helper (read-line pointer))) 
) 

;converting matrix of string to matrix of lists with strings inside 
(define (list-matr str-matr) 
    (define (helper str-matr line-num) 
    (cond 
     ((null? str-matr) '()) 
     ((= line-num 1) (cons (map (lambda (x) (string-append x "?")) (string-split (caar str-matr) "? ")) (helper (cdr str-matr) (+ line-num 1)))) 
     ((cons (string-split (caar str-matr) " ") (helper (cdr str-matr) (+ line-num 1)))))) 
    (helper str-matr 1)) 


;saving in file 
(define (writer file-name questions answers) 
    (cond 
    ((file-exists? file-name) (delete-file file-name))) 

    (write-to-file file-name (string-append (string-join questions) "\n")) 
    (define (helper cur-l ans) 
    (cond 
     ((null? ans)) 
     ((helper (write-to-file file-name (string-append (string-join (car ans)) "\n")) (cdr ans))))) 
    (helper '() answers) 
) 


(define (write-to-file path string) 
    (call-with-output-file path #:exists 'append 
    (lambda (newline) 
     (display string newline)))) 

команд для вызова функций.

(файл-читатель «data.txt»)

(писатель «data.txt» вопросы ответы)

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

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

спасибо.

ответ

0

Вы правы, что файл будет поврежден - он никогда не закрывается должным образом.

Не переписывая файл каждый раз, вам понадобится что-то вне обычной спецификации R5RS/R7RS, и я не знаю, что происходит с моей верхней частью любой (окончательной) SRFI, которая позволяет случайный доступ к файлам. Тем не менее, многие/большинство реализаций схемы предоставляют некоторую форму интерфейса ввода-вывода низкого уровня. Недостатком такого является то, что вам нужно будет тщательно отслеживать структуру, чтобы перезаписать или добавить только правильную сумму, которая, вероятно, будет более эффективной, чем переписывание всего файла.

Я бы порекомендовал реструктуризацию полностью. Во-первых, процедуры call-in-output-file/with-output-to-file автоматически перезаписывают выходной файл, если не указано иначе (в большинстве реализаций - хотя в спецификациях указано, что поведение не определено). Они также автоматически закроют файл по завершении. Аналогичное поведение для процедур call-in-input-file/with-input-from-file.

Вы можете, вероятно, все упрощать что-то вроде следующего:

; reader 
; this could be further simplified by replacing the cons call with 
; (cons (<parse-procedure> l) r), to parse the input at the same time 
(define (matrix-read filename) 
    (with-input-from-file filename (lambda() 
    (let loop ((l (read-line)) 
       (r '())) 
     (if (eof-object? l) 
      (reverse r) 
      (loop (read-line) (cons l r)))))) 

; I don't understand the input/output format... 

; writer 
(define (matrix-write filename data) 
    (with-output-to-file filename (lambda() 
    (for-each 
     (lambda (l) 
     ; again, I don't know the actual structure outside of a list 
     (display l) 
     (newline)) 
     data)))) 

Если вы объясните формат ввода, я могу изменить ответ.