Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Seeking help with reading a file

1 view
Skip to first unread message

Tony

unread,
Jan 24, 2006, 6:43:34 PM1/24/06
to
I am trying to read a file of characters into a string and so far have the
following:

(defun string<-file (file-path)
(with-open-file (in-stream file-path :direction :input)
(let ((input-string (make-string (file-length in-stream))))
(read-sequence input-string in-stream)
input-string)))

This works except that the end of the string contains a copy of some of the
final characters from the file. For example, if I read in a file
containing:

name,age
Tony,40
Fred,30
Mary,50
Sally,10

The resulting string when printed looks like this:

"name,age
Tony,40
Fred,30
Mary,50
Sally,10y,10" <== Note the "y,10" duplicated at the end.

I believe this is happening because I am running this on Windows, which uses
CRLF for newlines. When read into the string the sequence CRLF is being
replaced with a single newline character. This means that the string ends
up being a bit longer than necessary and read-sequence is filling the
remaining space by duplicating some of the characters.

I would be grateful if anyone could indicate a way of overcoming this.

Thankyou.

Tony
Melbourne, Australia


Eric Lavigne

unread,
Jan 24, 2006, 7:02:53 PM1/24/06
to
>I believe this is happening because I am running this on Windows, which uses
>CRLF for newlines. When read into the string the sequence CRLF is being
>replaced with a single newline character. This means that the string ends
>up being a bit longer than necessary and read-sequence is filling the
>remaining space by duplicating some of the characters.

Sounds like you are saying that read-sequence is broken. If so, perhaps
you could work around that problem by repeated use of read-line?

Edi Weitz

unread,
Jan 24, 2006, 7:06:44 PM1/24/06
to

(let* ((input-string (make-string (file-length in-stream)))
(pos (read-sequence input-string in-stream)))
(subseq input-string 0 pos))))

Or read the file line by line with READ-LINE and assemble the results
with WITH-OUTPUT-TO-STRING.

Cheers,
Edi.

--

Lisp is not dead, it just smells funny.

Real email: (replace (subseq "spam...@agharta.de" 5) "edi")

Edi Weitz

unread,
Jan 24, 2006, 7:09:12 PM1/24/06
to
On 24 Jan 2006 16:02:53 -0800, "Eric Lavigne" <lavign...@gmail.com> wrote:

> Sounds like you are saying that read-sequence is broken.

No, it's not broken, it works as described. His analysis is correct,
though, which is due to the fact that FILE-LENGTH reports the number
of octets on most Common Lisp implementations, i.e. it doesn't care
about encodings or line endings.

Wade Humeniuk

unread,
Jan 24, 2006, 7:57:40 PM1/24/06
to
Tony wrote:
> I am trying to read a file of characters into a string and so far have the
> following:
>
> (defun string<-file (file-path)
> (with-open-file (in-stream file-path :direction :input)
> (let ((input-string (make-string (file-length in-stream))))
> (read-sequence input-string in-stream)
> input-string)))
>
> This works except that the end of the string contains a copy of some of the
> final characters from the file. For example, if I read in a file
> containing:
>

I have also seen your problem because the file was created with
:overwrite instead of :supersede in CL's OPEN. If the new content
is shorter than the previous you can get garbage on the end using
an :overwrite. But here is a version that should work if you
are right , so....

(defun string<-file (file-path)
(with-open-file (in-stream file-path :direction :input)

(let ((input-string (make-array (file-length in-stream) :element-type 'character
:adjustable t :fill-pointer t)))
(setf (fill-pointer input-string) (read-sequence input-string in-stream))
input-string)))

Wade

Tony

unread,
Jan 25, 2006, 9:16:37 AM1/25/06
to
"Wade Humeniuk" <whumeniu+...@telus.net> wrote in message
news:82ABf.181228$OU5.30906@clgrps13...

Just tested your verson and its working fine.

Thanks very much for your help.

Tony


0 new messages