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
>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?
From: Edi Weitz
Subject: Re: Seeking help with reading a file
Date:
Message-ID: <u1wyxxj6f.fsf@agharta.de>
On 24 Jan 2006 16:02:53 -0800, "Eric Lavigne" <············@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.
--
Lisp is not dead, it just smells funny.
Real email: (replace (subseq ·········@agharta.de" 5) "edi")
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
"Wade Humeniuk" <··················@telus.net> wrote in message
···························@clgrps13...
> 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
Just tested your verson and its working fine.
Thanks very much for your help.
Tony
From: Edi Weitz
Subject: Re: Seeking help with reading a file
Date:
Message-ID: <u64o9xjaj.fsf@agharta.de>
On Tue, 24 Jan 2006 23:43:34 GMT, "Tony" <··········@nowhere.com> 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:
>
> 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.
(defun string<-file (file-path)
(with-open-file (in-stream file-path :direction :input)
(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 ·········@agharta.de" 5) "edi")