Author Topic: write-line  (Read 9996 times)

0 Members and 1 Guest are viewing this topic.

rude dog

  • Guest
write-line
« on: January 30, 2004, 11:56:54 AM »
How would you accomplish writing a setq'd value (A1) to a file
(defun c:WT (\ A1 LOG)
(setq A1 '(HERE IT IS!))
(setq LOG (open "RC-WT.TXT" "w"))
 (write-line A1 LOG)
 (close LOG)
)
(PRINC)

daron

  • Guest
write-line
« Reply #1 on: January 30, 2004, 12:23:00 PM »
Code: [Select]
(defun c:WT (\ A1 a) ;|LOG is a bad variable. It's a function and you will not get the desired results.|;
     (setq A1 "HERE IT IS!");This will create a list of three empty items, HERE, IT & IS
     (setq a (open "RC-WT.TXT" "w"));again, LOG
     (write-line A1 a);Change LOG
     (close a);same
)

rude dog

  • Guest
write-line
« Reply #2 on: January 30, 2004, 12:38:26 PM »
didnt know...again :x ....thank you :D

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
write-line
« Reply #3 on: January 30, 2004, 02:46:18 PM »
Just remember every thing that goes to the open file must be a string.
Example:
Code: [Select]

Command: (setq fo (open "c:/str_test.txt" "w"))
#<file "c:/str_test.txt">

Command: (setq test (list 1 2 3))
(1 2 3)

Command: (write-line test fo) <-bad because 'test' is a list
; error: bad argument type: stringp (1 2 3)

Command: (write-line (vl-princ-to-string test) fo) <- good converted to a string
"(1 2 3)"

Command: (setq test (list "a" "b" "c"))
("a" "b" "c")

Command: (write-line test fo) <- bad it's still a list
; error: bad argument type: stringp ("a" "b" "c")

; write each item in the list to the open file since it is a string
Command: (foreach item test (write-line item fo)) <-good

; testing for a string
Command: (setq test "this is a string")
"this is a string"

(if (= (type test) 'STR)
  (prompt "Yes it's a string")
  (prompt "No it's not")
  )
(princ)
Yes it's a string

Command: (setq test 123)
123

(if (= (type test) 'STR)
  (prompt "Yes it's a string")
  (prompt "No it's not")
  )
(princ)
No it's not
TheSwamp.org  (serving the CAD community since 2003)

Craig

  • Guest
write-line
« Reply #4 on: January 30, 2004, 02:55:55 PM »
Also keep in mind when you use (open "RC-WT.TXT" "w") and want to write to the same file the "w" switch will overwrite the original file. To add to a file use the "a" switch.
Quote
r Open for reading
w Open for writing. If filename does not exist, a new file is created and opened. If filename already exists, its existing data is overwritten. Data passed to an open file is not actually written until the file is closed with the close function.
a Open for appending. If filename does not exist, a new file is created and opened. If filename already exists, it is opened and the pointer is positioned at the end of the existing data, so new data you write to the file is appended to the existing data.


daron

  • Guest
write-line
« Reply #5 on: January 30, 2004, 03:01:04 PM »
I was going to suggest that. If you do use append, you'll notice everything is on the same line. Use "\n" at the end or beginning of your code to move to the next line.

Anonymous

  • Guest
write-line
« Reply #6 on: January 31, 2004, 02:43:15 AM »
Mark

What a hand...excellent example..I really wanted to reply
to your newbie challenge (I think Im the only one) but I have been totally engulfed in a program im trying to put together I feel inclined to post what I have done on it so far because of the knowledge you share....." (vl-princ-to-string)" what tongue is this command...havent seen it in the book


(defun c:KLT (/ ES LG)
(princ "\nPick layer to keep thawed <Enter to exit>:")
(while
(setq ES (car (entsel)))
(setq ES (entget ES))
(setq EL (cdr (assoc 8 ES)))
(setq EL (strcat EL","))
(setq LG (append LG (LIST EL)))
(setq CS (vl-princ-to-string LG))
(princ "\n Layers to remain thawed:")
(prin1 CS)
)
(setq LL CS)
(setq LAY (open "c:/LAY-INFO.TXT" "w"))                      
(write-line LL LAY)
(close LAY)
(princ)
)

ultimate goal is to strip parenthisis and space from string extracted by the routine (ex.) (DIM, CENTER, WRK,) (TO:) DIM,CENTER,WRK,
so I can call these names from txt file back to command prompt for "thawing"......routine will freeze every layer except "0" go back and thaw these "extracted layer names" from txt file. do some collision checking and then thaw "*"

rude dog

  • Guest
write-line
« Reply #7 on: January 31, 2004, 02:45:51 AM »
:oops: @###@**#@##Last post was from Rude Dog ....very tired

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
write-line
« Reply #8 on: January 31, 2004, 11:02:23 AM »
Now that I understand what you are doing. :D Take a look at the following code. You could add a lot more error checking to this but let's take it one step at a time.
Code: [Select]

(defun c:KLT (/ str ent lay_name LAY)

  ;; create empty string
  (setq str "")

  (while
    ;; loop while selection continues
    (setq ent (car (entsel "\nSelect an item <enter to exit>: ")))

    ;; extact layer name from selected entity
    (setq lay_name (cdr (assoc 8 (entget ent))))

    ;; show the user which layer they picked
    (prompt lay_name)

    ;; create one long string of layer names
    (setq str (strcat str (strcat lay_name ",")))

    ) ; end of loop

  ;; we need to make sure 'str' is not empty
  (if (not (= str ""))
    (progn
      ;; remove the last ',' from the string
      (setq str (substr str 1 (1- (strlen str))))
      (setq LAY (open "C:/LAY-INFO.TXT" "w"))
      (write-line str LAY)
      (close LAY)
      )
    )
  (princ)
  )
TheSwamp.org  (serving the CAD community since 2003)

rude dog

  • Guest
write-line
« Reply #9 on: February 01, 2004, 11:10:06 AM »
Mark,
How do you improve on perfection.....its not gonna happin this is beautiful...
 ;; create one long string of layer names
    (setq str (strcat str (strcat lay_name ",")))  :shock:
so small yet so resourceful....the last comma on the last layer name would not have hurt anything but why not take it out and have a flawess routine
I dont know what else to say dude...
Thanks,
Rudy

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
write-line
« Reply #10 on: February 01, 2004, 11:15:06 AM »
Does it all make sense or did I loose you on some of it?
TheSwamp.org  (serving the CAD community since 2003)

rude dog

  • Guest
write-line
« Reply #11 on: February 01, 2004, 11:36:44 AM »
I believe i got it....I'll finish the rest during the week some time..very busy with kids, work, family and of course super bowl  :)

rude dog

  • Guest
write-line
« Reply #12 on: February 01, 2004, 11:40:12 AM »
When I get the rest done I'll post it for critiquing

rude dog

  • Guest
write-line
« Reply #13 on: February 01, 2004, 06:12:51 PM »
Spoke too soon...there is sumthin' I do not understand I didnt understand why the "if" statement and the "progn" statement where necessary in this program....I omitted them and it still seems to work fine...Are they in there because its just "good programming habits" that you have, that I dont understand or does omitting them sacrafice the integrity of the routine?
I hope this is not coming across wrong dude, just curious :wink:



(defun c:LTC (/ str ent lay_name LAY)

  ;; create empty string
  (setq str "")

  (while
    ;; loop while selection continues
    (setq ent (car (entsel "\nSelect an item <enter to exit>: ")))

    ;; extact layer name from selected entity
    (setq lay_name (cdr (assoc 8 (entget ent))))

    ;; show the user which layer they picked
    (prompt lay_name)

    ;; create one long string of layer names
    (setq str (strcat str (strcat lay_name ",")))

    ) ; end of loop

  ;; we need to make sure 'str' is not empty
  ;(if (not (= str ""))
    ;(progn
      ;; remove the last ',' from the string
      (setq str (substr str 1 (1- (strlen str))))
      (setq LAY (open "C:/LAY-INFO.TXT" "w"))
      (write-line str LAY)
      (close LAY)
      ;)
    ;)
  (princ)
  )

Matt Stachoni

  • Guest
write-line
« Reply #14 on: February 01, 2004, 07:06:48 PM »
Can I ask why you want to write layer names to a file in such a manner?

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
write-line
« Reply #15 on: February 02, 2004, 12:26:50 AM »
Yes, I am curious too.

Here are some (if) examples

Code: [Select]
(if (this is true)
   (do this)
); endif

(if (this is false)
   (don't do this)
   (do this)
); endif

(if (this is true)
   (progn
        do all of this
        and this
        and this
    )
   (don't do this)
); endif

(if (this is false)
   (don't do this)
   (progn
        do all of this
        and this
        and this
    )
); endif


So you see the progn is a way to group code together.
The (if) stmt will execute the group of code when true and
will execute the second group of code when false,
if there is a second group of code. If you forget the (progn) only the first
line of code will be executed if true and the rest skipped.
There are other ways to group code together and you will learn them in time.

The (cond) stmt on the other hand executes the all of code following
a true condition and then exits the condition stmt.

Code: [Select]
(cond
  ((= 1 0)
    none of this will get executed
    because the conditions is false
  ) ; end cond 1

  ((= 1 1)
     do all of this because it is true
     and this
     and this
   ) ; end cond 2

   ((= 2 2)
     none of this will get
     executed even if it is true
     because the prior stmt was true
   ) ; end cond 3

   (T
     This is often placed at the last position
     in a condition statement and will be executed
     if all the prior conditions are false
     if any one of the above conditions are true
      this will not be executed
   ) ; end cond 4
) ; end cond stmt
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
write-line
« Reply #16 on: February 02, 2004, 05:33:15 AM »
I followed this thread on and off and feel some comments should be made on the topic of outputting to files.

It's true that OPEN only streams ASCII files. It's also true that WRITE-LINE can only write strings to a file, but it is certainly possible to write any data type. It just depends on the function used to write the data. Let's take a look at them by using an example: WRITE-LINE, PRINC, PRINT and PRIN1.

First make some non-string data, in this case a list:

(setq alst '(1 2 3 4 5))
-> (1 2 3 4 5)


Then create a file:

(setq fn (open "C:\\abc.txt" "w"))
-> #<file "C:\\abc.txt">

Now try the various functions to write the data. To keep track of which function was used, we'll write the functions as a string before writing the data. We'll also use a newline character to see how they each treat control characters.

First WRITE-LINE. As Mark pointed out, it only handles strings so we'll need to convert the list to a string using VL-PRINC-TO-STRING:

(write-line "\nwrite-line:" fn)
-> "\nwrite-line:"

(write-line (vl-princ-to-string alst) fn)
-> "(1 2 3 4 5)"

Then PRINC, PRINT and PRIN1. These functions write any data types - just like they would at the command line:

(princ "\nprinc:" fn)
-> "\nprinc:"
(princ alst fn)
-> (1 2 3 4 5)

(print "\nprint:" fn)
-> "\nprint:"
(print alst fn)
-> (1 2 3 4 5)

(prin1 "\nprin1:" fn)
-> "\nprin1:"
(prin1 alst fn)
-> (1 2 3 4 5)

Now close the file and open it (here just using Notepad):

(close fn)
-> nil
(startapp "notepad.exe" "C:\\abc.txt")
-> 33

The file should look like this (first blank line included):

Code: [Select]


write-line
(1 2 3 4 5)

princ:(1 2 3 4 5)
"\nprint:"
(1 2 3 4 5) "\nprin1:"(1 2 3 4 5)


WRITE-LINE: Writes its string argument with a trailing newline character. Control characters are output as their ASCII representation; a newline character creates a linefeed, a tab character creates a tabulation etc.
Notice that the automatic newline character is put at the end of the string. The first blank line in the example came from the explicit "\n"-character, but the second blank line was caused by the combination of WRITE-LINE's newline and PRINC' explicit newline character.

PRINC: Works like WRITE-LINE except that it does not create a new line. Also, neither PRINC, PRINT nor PRIN1 are limited to outputting strings.

PRINT: Outputs the literal value of its argument, which means that strings become quoted and control characters are expanded into their control character codes. It also prints a leading newline character and a trailing space. Notice that "\nprint:" was output on a new line and that it has a trailing space (put the cursor at the end of the line to see it).

PRIN1: Works like PRINT, except that it doesn't print a leading newline character and a trailing space. Notice that the space before "\nprin1:" came from the previous PRINT statement and that PRIN1 did not jump to a new line.

SMadsen

  • Guest
write-line
« Reply #17 on: February 02, 2004, 06:10:34 AM »
Matt, I think Rude Dog is merely using this as a small tool to freeze and/or thaw some layers. The string is perfectly legal to submit at Thaw, Freeze, On and Off prompts in the layer command.
I also thought that, firstly, it should at least check for duplicate layer names and trailing commas and, secondly, that much more sophisticated methods could be used. But as a small fix it does the job.
Rude Dog, just don't pass it on to anyone :D
 
Quote from: Rude Dog
... I didnt understand why the "if" statement and the "progn" statement where necessary in this program....I omitted them and it still seems to work fine.


The IF statement that checks for an empty string is needed when the command is invoked but the user simply presses Enter and exits the command without doing anything.
It's not just 'good programming practice' - it prevents the file from being manipulated (and thereby overridden) without a reason to manipulate it.

rude dog

  • Guest
write-line
« Reply #18 on: February 02, 2004, 06:44:23 AM »
Matt
just trying to use one continous string(of layer names) to only show the entities I pick for viewing and freezing everything else out. and practice

rude dog

  • Guest
write-line
« Reply #19 on: February 02, 2004, 06:50:54 AM »
CAB,SMadsen thanks for your comments it ususallly takes me a day or two to absorb and try to retain practical hints and possibly stir up some questions.....I'm sure there is more complicated ways to do this but I'm sure after the code is written and after using it for a while I'll think of other facets to add....(with help of course :D )

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
write-line
« Reply #20 on: February 02, 2004, 08:11:45 AM »
Using what SMadsen has given us we could re-write the program using a list of collected layer names.
Code: [Select]

(defun c:KLT (/ fo ent lay_name lst)

  ;; open a file for writing
  (setq fo (open "C:/LAY-INFO.TXT" "w"))

  (if
    (findfile "C:/LAY-INFO.TXT"); make sure the file exists, overkill?
    (while
      ;; loop while selection continues
      (setq ent (car (entsel "\nSelect an item <enter to exit>: ")))

      ;; extact layer name from selected entity
      (setq lay_name (cdr (assoc 8 (entget ent))))

      ;; show the user which layer they picked
      (prompt lay_name)

      ;; create a list of layer names
      ;; do not add 'lay_name' to list if it already exists
      ;; in 'lst'
      (if
        (not
          (vl-position lay_name lst); could also use the 'member' function here
          )
        (setq lst (cons lay_name lst))
        ; else
        (prompt " has already been selected...")
        )
      ) ; end of loop
    )

  ;; now process the list of layer names
  ;; test the length of the list to make sure it's
  ;; greater than 0 (in other words in contains something)
  (if (> (length lst) 0)
    ;; for each item in the list
    (foreach i lst (princ (strcat i ",") fo))
    )

  (close fo); close the open file handle
  (princ)
  )
TheSwamp.org  (serving the CAD community since 2003)

Matt Stachoni

  • Guest
write-line
« Reply #21 on: February 02, 2004, 01:00:00 PM »
Quote from: Rude Dog
Matt
just trying to use one continous string(of layer names) to only show the entities I pick for viewing and freezing everything else out. and practice


Well, yeah, I gathered that much, but are you actually writing the string to a file as a means of saving it for future use? Or are you writing to a file for sheer learning practice?

Generally speaking, if I was to use this in "production code," I would save it as a global variable or write it to the registry if I had to carry it over from one drawing to another. Not to be rude, but using file I/O for this task is kind of a waste of resources.

rude dog

  • Guest
write-line
« Reply #22 on: February 02, 2004, 11:06:40 PM »
Matt
I guess what your thinking is why not just leave it in a list and loop the thawing process till the list is empty...huh...this would be good as well...this whole idea was sparked from a newbie challenge and just kinda grew for me from there...and man, I sure did get alot of info I did not previously know.
But this by no means was a waste for me and I hope anyone that gave a hand feels the same.....looking foward to seeing some of your ideas
RD

Matt Stachoni

  • Guest
write-line
« Reply #23 on: February 03, 2004, 05:55:46 PM »
Quote from: Rude Dog
Matt
I guess what your thinking is why not just leave it in a list and loop the thawing process till the list is empty...huh...this would be good as well...


Well, I'm thinking that if you want to process the layer list in a drawing, you can create the string (with the "," delimeter) and feed it to the layer command just fine. I do that in my layer utilities myself.

What I would object to is writing the name to a file. File I/O is a lot more expensive from a processing standpoint and doesn't contribute to efficient code in this example.

The only tip I would give right now is, always strive to make your code leaner, cleaner and cool.