PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, May 13, 2022

[FIXED] How to change the use of Common Lisp `with-open-file` so that elements are appended inside a list in a file?

 May 13, 2022     append, common-lisp, file, format, io     No comments   

Issue

I am using Common Lisp (SBCL). Currently, I can write a file appending lists. In order to illustrate, let's first define some variables to make it easier to understand:

(defvar example-1 '((d-1 u-1) (i-1) (i-2)))
(defvar example-2 '((d-2 u-2) (i-1) (i-2)))

Now, in the REPL:

CL-USER> (with-open-file (str "/home/pedro/miscellaneous/misc/tests-output/stack-overflow.lisp"
                         :direction :output
                         :if-exists :append
                         :if-does-not-exist :create)
           (format str " ~S ~%" example-1))
    
CL-USER> (with-open-file (str "/home/pedro/miscellaneous/misc/tests-output/stack-overflow.lisp"
                         :direction :output
                         :if-exists :append
                         :if-does-not-exist :create)
           (format str " ~S ~%" example-2))

If I go to checkout the file "stack-overflow.lisp", I can see:

 ((D-1 U-1) (I-1) (I-2)) 
 ((D-2 U-2) (I-1) (I-2)) 

Ok. This is close to what I want.

However, I would like to have everything wrapped in a list:

(

 ((D-1 U-1) (I-1) (I-2)) 
 ((D-2 U-2) (I-1) (I-2)) 

)

Thus, every time something is "appended" to the file, it should be inside this list. I am changing this because it will make this file easier to read and work on. I will need to filter the elements added.

What do I need to change in with-open-file function to have this output?


Solution

Use a single call to WITH-OPEN-FILE and combine everything into a single list.

(with-open-file (str "/home/pedro/miscellaneous/misc/tests-output/stack-overflow.lisp"
                         :direction :output
                         :if-exists :overwrite
                         :if-does-not-exist :create)
  (pprint (list example-1 example-2) str))

If you want to append to the list every time you write, you need to read the list, append to the list, then overwrite the file with the updated list.

(defun append-to-list-in-file (filename new-item &aux contents) ;;;;
  (setq contents (list)) ;; default in case reading fails
  (ignore-errors
    (with-open-file (str filename :direction :input)
      (setq contents (read str))))
  (setq contents (nconc contents (list new-item)))
  (with-open-file (str filename :direction :output :if-exists :overwrite)
    (write contents :stream str)))


Answered By - Barmar
Answer Checked By - Gilberto Lyons (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing