### Author Topic: Testing a string for a number  (Read 4134 times)

0 Members and 1 Guest are viewing this topic.

#### whdjr

• Guest
##### Testing a string for a number
« on: April 24, 2006, 11:56:31 AM »
What would be a good and easy/quick way to test a string to see if it is a number?

(atoi "aaa")   ==> 0
(atoi "0")      ==> 0
(atoi "111")  ==> 111

Any ideas?

#### CAB

• Global Moderator
• Seagull
• Posts: 10388
##### Re: Testing a string for a number
« Reply #1 on: April 24, 2006, 12:09:20 PM »
Code: [Select]
`(numberp (read (substr str 1 1)))`or
Code: [Select]
`(numberp (read str))`
I've reached the age where the happy hour is a nap. (°Ώ°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970

#### Alexander Rivilis

• Bull Frog
• Posts: 212
• Programmer from Kyiv (Ukraine)
##### Re: Testing a string for a number
« Reply #2 on: April 24, 2006, 12:11:18 PM »
(distof "aaa")  ==> nil
(distof "0") ==> 0.0
(distof "111") ==> 111.0

#### T.Willey

• Needs a day job
• Posts: 5241
##### Re: Testing a string for a number
« Reply #3 on: April 24, 2006, 12:13:26 PM »
I think this might work.  Written on the fly.

Code: [Select]
`(defun IsStrNums (String)(and (mapcar  '(lambda (x) (>= 48 x 57))  (vl-string->list String) )))`
I think that is the right function to use (vl-string->list), but not sure.

Edit:  Change the test to greater than or equal, not less than or equal.
« Last Edit: April 24, 2006, 12:25:46 PM by T.Willey »
Tim

I don't want to ' end-up ', I want to ' become '. - Me

#### CAB

• Global Moderator
• Seagull
• Posts: 10388
##### Re: Testing a string for a number
« Reply #4 on: April 24, 2006, 12:16:57 PM »
That's a nice one Rivilis.
Code: [Select]
`(distof "2'-3 1/2\"")27.5`
I've reached the age where the happy hour is a nap. (°Ώ°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970

#### John Kaul (Se7en)

• Needs a day job
• Posts: 9484
##### Re: Testing a string for a number
« Reply #5 on: April 24, 2006, 12:21:48 PM »
Oho, potential fun: I think if i remeber correctly numbers take up codes 48 and up in ascii codes. ... 0 = 48 1 = 49...

TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

#### Alexander Rivilis

• Bull Frog
• Posts: 212
• Programmer from Kyiv (Ukraine)
##### Re: Testing a string for a number
« Reply #6 on: April 24, 2006, 12:33:34 PM »
That's a nice one Rivilis.
Code: [Select]
`(distof "2'-3 1/2\"")27.5`
On my AutoCAD: (distof "2'-3 1/2\"") ==> nil because LUNITS is setting to 2
This function is dependent on LUNITS variable. If you need test only decimal number (not architectural, nor engineering)
you must use (distof val 2)  - val is a testing string.

#### MP

• Seagull
• Posts: 17662
• Have thousands of dwgs to process? Contact me.
##### Re: Testing a string for a number
« Reply #7 on: April 24, 2006, 01:23:11 PM »
On my AutoCAD: (distof "2'-3 1/2\"") ==> nil because LUNITS is setting to 2
This function is dependent on LUNITS variable. If you need test only decimal number (not architectural, nor engineering)
you must use (distof val 2)  - val is a testing string.

Perhaps this may be useful --

Code: [Select]
`(defun MyDistOf ( string / result )    (vl-some       '(lambda (mode)            (setq result                (distof                    string                    mode                )            )        )       '(2 3 5 4 1)    )    result)`
From here.
Engineering Technologist  CAD Specialist  Programmer Analyst
Design  Drafting  Document Control  Automation.

#### whdjr

• Guest
##### Re: Testing a string for a number
« Reply #8 on: April 24, 2006, 01:24:07 PM »
Thanks for the reply guys those are some great examples but I think for simplicity sake I will use the method suggested by CAB.

...
Code: [Select]
`(numberp (read str))`

Thanks again guys,

#### MP

• Seagull
• Posts: 17662
• Have thousands of dwgs to process? Contact me.
##### Re: Testing a string for a number
« Reply #9 on: April 24, 2006, 01:33:12 PM »
I don't know the context you're going to use it Will but do be careful --

Command: (numberp (read "123 abc")) => T

Command: (numberp (mydistof "123 abc")) => nil

Should your host application consider "123 abc" a number?

Engineering Technologist  CAD Specialist  Programmer Analyst
Design  Drafting  Document Control  Automation.

#### whdjr

• Guest
##### Re: Testing a string for a number
« Reply #10 on: April 24, 2006, 01:41:36 PM »
Thanks Michael,

The list will either be a number or a string not both so I think the numberp will work fine.  Thanks for your code though it definitely covers all the bases.

#### whdjr

• Guest
##### Re: Testing a string for a number
« Reply #11 on: April 24, 2006, 01:51:12 PM »
Michael,

Upon further trials:

Command: (numberp (read "123 abc")) => T -> In the VLIDE it strips everything off after the space.

Command: (numberp (read "123abc")) => Nil  If you remove the space then it nil's out.

Just FYI.

#### MP

• Seagull
• Posts: 17662
• Have thousands of dwgs to process? Contact me.
##### Re: Testing a string for a number
« Reply #12 on: April 24, 2006, 01:58:25 PM »
Precisely why I posted that example Will.

An aside, here's another variant I wrote that is relatively bomb proof --

Code: [Select]
`(defun distanceof ( x  / result )   (vl-catch-all-apply      '(lambda ()           (vl-some              '(lambda (units) (setq result (distof x units)))               (list (getvar "lunits") 4 5 2 1)           )       )   )       result)`
From here.

Engineering Technologist  CAD Specialist  Programmer Analyst
Design  Drafting  Document Control  Automation.

#### whdjr

• Guest
##### Re: Testing a string for a number
« Reply #13 on: April 24, 2006, 02:04:39 PM »
Thanks Michael,

I like that one a little better because once it catches a T it stops processing.  Very COOL.

Thanks,

#### CAB

• Global Moderator
• Seagull
• Posts: 10388
##### Re: Testing a string for a number
« Reply #14 on: April 24, 2006, 02:33:39 PM »
Thanks Michael..

Here is something to consider, although may not be relevant to Will.

Code: [Select]
`Command: test1                             Command: test2                                                                                                             *--> 3.5        gives number: 3.5          *--> 3.5        gives number: 3.5       " type: " 2                                                                        *--> 3 1/2      gives number: 3.5          *--> 3 1/2      gives number: 3.5       " type: " 2                                                                        *--> 3 1/2"     gives number: 3.5          *--> 3 1/2"     gives number: 3.5       " type: " 3                                                                        *--> 3 1/2'     gives number: 42.0         *--> 3 1/2'     gives number: 42.0      " type: " 3                                                                        *--> 3-1/2'     gives number: 42.0         *--> 3-1/2'     gives number: 42.0      " type: " 3                                                                        *--> 3'-1"      gives number: 37.0         *--> 3'-1"      gives number: 37.0      " type: " 3                                                                        *--> 3' -1"      gives number: 3             **  Invalid Number  **  3' -1"        " type: " 6                                                                        *--> 3'- 1"      gives number: 3             **  Invalid Number  **  3'- 1"        " type: " 6                                                                        *--> 3'-1       gives number: 37.0         *--> 3'-1       gives number: 37.0      " type: " 3                                                                        *--> 3' 1       gives number: 37.0         *--> 3' 1       gives number: 37.0      " type: " 3                                                                        *--> 3' 1"      gives number: 37.0         *--> 3' 1"      gives number: 37.0      " type: " 3                                                                        *--> 3' 1 1/2   gives number: 37.5         *--> 3' 1 1/2   gives number: 37.5      " type: " 3                                                                        *--> 3'-1-1/2   gives number: 37.5         *--> 3'-1-1/2   gives number: 37.5      " type: " 3                                                                        *--> 3' 1 1/2"  gives number: 37.5         *--> 3' 1 1/2"  gives number: 37.5      " type: " 3                                                                        *--> 3' 1.5     gives number: 37.5         *--> 3' 1.5     gives number: 37.5      " type: " 3                                                                        *--> 3' .5      gives number: 36.5         *--> 3' .5      gives number: 36.5      " type: " 3                                                                        *--> 3'.5      gives number: 36.5          *--> 3'.5      gives number: 36.5       " type: " 3                                                                          **  Invalid Number  **  10-1               **  Invalid Number  **  10-1                                                                                             *--> -10        gives number: -10.0        *--> -10        gives number: -10.0     " type: " 2                                                                          **  Invalid Number  **  -10-1              **  Invalid Number  **  -10-1                                                                                            *--> .5         gives number: 0.5          *--> .5         gives number: 0.5       " type: " 2                                                                        *--> 0.5        gives number: 0.5          *--> 0.5        gives number: 0.5       " type: " 2                                                                        *--> 5 -2       gives number: 5              **  Invalid Number  **  5 -2          " type: " 6                                                                        *--> 1/2        gives number: 0.5          *--> 1/2        gives number: 0.5       " type: " 2                                                                        *--> 1/2"       gives number: 0.5          *--> 1/2"       gives number: 0.5       " type: " 3                                                                        *--> 9 1/2      gives number: 9.5          *--> 9 1/2      gives number: 9.5       " type: " 2                                                                        *--> 1.55E+01   gives number: 15.5         *--> 1.55E+01   gives number: 15.5      " type: " 2                                                                          **  Invalid Number  **  5A                 **  Invalid Number  **  5A                                                                                               *--> 5 A        gives number: 5              **  Invalid Number  **  5 A           " type: " 6`

Code: [Select]
`(defun c:test1 (/ txt txtlst num)  (setq txtlst         (list  "3.5       "   ; type:  2                "3 1/2     "   ; type:  2 ?5                "3 1/2\"    "  ; type:  4                "3 1/2'    "   ; type:  4                "3-1/2'    "   ; type:  4                "3'-1\"     "  ; type:  4                "3' -1\"     " ; Invalid Number                "3'- 1\"     " ; Invalid Number                "3'-1      "   ; type:  4                "3' 1      "   ; type:  4                "3' 1\"     "  ; type:  4                "3' 1 1/2  "   ; type:  4                "3'-1-1/2  "   ; type:  4                "3' 1 1/2\" "  ; type:  4                "3' 1.5    "   ; type:  4                "3' .5     "   ; Invalid Number                "3'.5     "    ; type   3                "10-1      "   ; Invalid Number                "-10       "   ; type:  2                "-10-1     "   ; Invalid Number                ".5        "   ; type:  2                "0.5       "   ; type:  2                "5 -2      "   ; type:  6                "1/2       "   ; type:  2 ?5                "1/2\"      "  ; type:  4                "9 1/2     "   ; type:  2 ?5                "1.55E+01  "   ; type:  2                "5A        "   ; Invalid Number                "5 A       "   ; type:  6         )  )  (setq idx -1)  ;;  distof will tollerate trailing spaces but not any other character  ;;  therefore READ can be used to extract numbers followed by characters IF  ;;  there is a space behing the number (read "12 A") = 12 (read "12a") = "12a"  (while (< (setq idx (1+ idx)) (length txtlst))    (setq txt (nth idx txtlst))    ;;  must be tested in this order (2 1 5 4 3)    ;; if you use (1 2 3 4 5) you will not get any 2 4 or 5 results    ;;  further test result in inconsistancies with 3&4 and 5 types    (cond ((setq num (distof txt 2))           (setq typ 2)          )          ((setq num (distof txt 1))           (setq typ 1)          )          ((setq num (distof txt 5))           (setq typ 5)          )          ((setq num (distof txt 3))           (setq typ 3)          )          ((setq num (distof txt 4))           (setq typ 4)          )          ((setq num (read txt))           (setq typ 6)          ); get number if followed by a space "10 a" = 10           ;; (read "10a") = "10a" so you must test result with           ;;   (numberp "10a") results in 'not a number'    )    (if (numberp num) ;  Got a valid number      (progn        (prompt (strcat "\n*--> " txt " gives number: "))        (princ num)        (print " type: ")        (princ typ)      )      (prompt (strcat "\n  **  Invalid Number  **  " txt))    )  )  (princ))`
test2
Code: [Select]
`  (while (< (setq idx (1+ idx)) (length txtlst))    (setq txt (nth idx txtlst))        (setq num (distanceof txt))    (if (numberp num) ;  Got a valid number      (progn        (prompt (strcat "\n*--> " txt " gives number: "))        (princ num)        (print)      )      (prompt (strcat "\n  **  Invalid Number  **  " txt))    )  )`
I've reached the age where the happy hour is a nap. (°Ώ°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970