d0m1n1c
d0m1n1c

Reputation: 157

Why is prolog confused by my input file

I'm writing a list of lists to a file with

choice(2, X):- 
  nl, write('\tRead roster from a file:'),nl, write('\tEnter file name: '),read(N),
  open(N,write,Stream), write(Stream, X), nl(Stream),close(Stream), write('\tRoster stored.'),nl,nl,menu(X).

then I'm reading it with

choice(1, X):- 
  nl, write('\tStore roster to a file:'),nl, write('\tEnter file name: '),read(N),
  open(N,read,Stream), read(Stream, Y), close(Stream), write('\tRoster stored.'),nl,nl,menu(Y).

this is the contents of a sample from choice(2,X) that I tried to read with choice(1,X).

[[[49,48,48],[100,97,109,105,101,110],100]]

when I try to read it gives the error

ERROR: r2:1:44: Syntax error: Unexpected end of file

Upvotes: 0

Views: 3391

Answers (2)

Sergii Dymchenko
Sergii Dymchenko

Reputation: 7209

As @Grzegorz correctly said, to be able to read a term with read it needs to end with a full stop.

But I don't think that a correct solution to your problem is to read as codes. I think the better way is just to write full stop to the file.

The recommended way, I believe, is to use write_term with fullstop(true) option instead of write. But this is not working on my version of SWI-Prolog.

The easiest way is just to write full stop explicitly with write(Stream, '.').

Upvotes: 3

Grzegorz Adam Kowalski
Grzegorz Adam Kowalski

Reputation: 5565

You get this error because read/2 can only read full prolog terms terminated with .. Contents of your file aren't terminated with dot, so end of file is "unexpected".

My suggestion is that you should modify that:

open(N,read,Stream), read(Stream, Y), close(Stream)

Into that:

open(N,read,Stream), read_line_to_codes(Stream, Codes), close(Stream), atom_codes(Atom, Codes), atom_to_term(Atom, Y, [])

Above code reads one line of character data, converts it to atom and then converts it to prolog term unified with Y.

This is my input and output from interpreter to prove it works:

?- open('test2.txt',read,Stream), read_line_to_codes(Stream, Codes), close(Stream), atom_codes(Atom, Codes), atom_to_term(Atom, List, []).

List = [[[49, 48, 48], [100, 97, 109, 105, 101, 110], 100]].

Contents of file test2.txt: [[[49,48,48],[100,97,109,105,101,110],100]]

(no dot on the end)

Upvotes: 3

Related Questions