dealing with "error: misplaced dot on input"

Joe Burke

Usenet Archive
Joined
May 28, 2000
Messages
653
Reaction score
0
Following is a sub-function within a program which increments numbers in mtext or text strings.

Input needs to be a number, and should allow values like .25 or 25 or 25.0. The numeric value returned should not be altered in any way. Except for converting input ..25 to 0.25 to avoid the "misplaced dot on input" error. Input integer, return integer. Input real, return real. Input something that doesn't represent a number, loop until a number is entered.

(defun GetNumber ( message / num )
(princ message)
(setq num (getstring))
(if (= "." (substr num 1 1))
(setq num (strcat "0" num))
)
(if (numberp (read num))
(read num)
(GetNumber "Value must be a number: ")
)
) ;end

Seems to work:

Command: (GetNumber "Input value: ")
Input value: .25
0.25

Command: (GetNumber "Input value: ")
Input value: 25
25

Command: (GetNumber "Input value: ")
Input value: 25.0
25.0

Command: (GetNumber "Input value: ")
Input value: a
Value must be a number: 25
25

Comments, suggestions and spitballs welcome.
Joe Burke
 
Pretty good, Joe!

Now how about those architects that want to enter "1/4"? <G>

Actually, you might want to address "-.5"
 
Hi John,

Though I deal with architects who may prefer fractions, I'm not one of them. I use Engineering units instead.

That aside, agreed, I need some method to deal with "-.5". I haven't figured it out yet. But I guess there is some way.

Thanks
Joe
 
Joe,

Take a look at this. Little testing, but I think it will work for negatives and fractions too.

(defun getnum (/ a)
(initget 128)
(while (not a)
(setq a (getint "\nEnter a number: "))
(if (and a
(not (numberp a)))
(setq a (distof a))
)
)
a
)
 
Unless I'm missing something really obvious, you're
description below sounds exactly like a description
of what (distof) does.

Your route involves the "blind" use of (read) on a
string, which is dangerous because a user can enter
any malformed LISP expression, which results in an
error. If you're going to do that then its necessary
to wrap the call to (read) in a (vl-catch-all-apply),
or your program is going to crash.

This would seem to be a bit safer, as it doesn't try
to (read) the string til its confirmed to be a valid
number:

(defun getnumber (msg / value result)
(while (not result)
(setq value (getstring msg))
(if (distof value)
(setq result (read value))
(princ "\nMust enter a number,")
)
)
)
 
Tony,

If I pass .25 to your function, I get misplaced dot on input. I guess because:

Command: (read ".25")
; error: misplaced dot on input

Seems I can't use distof (Ken) because it returns a real when passed a string representing an integer. That and the misplaced dot error is what caused me to revisit this topic. It was discussed here in October of last year.

Thanks
Joe Burke
 
Joe,

If you notice I acount for that by using getint with (initget 128) if an integer is entered then an integer is returned. If a real is entered then a string is returned, distof converts to a real.
 
Herman,

Command: (str2num .25)
; error: misplaced dot on input

Command: (type .25)
; error: misplaced dot on input

That's why I need:

(if (= "." (substr num 1 1))
(setq num (strcat "0" num))
)

Does this sound familiar? We kicked it around last year. :-)

Thanks for your reply.
Joe Burke
 
Expanding on Tony's function:

(defun getnumber (msg / value result)
(while (not result)
(setq value (getstring msg))
(if (distof value)
(if (or (wcmatch value "*`.*")
(wcmatch value "*[/\]*")
)
(setq result (distof value))
(setq result (atoi value))
)
(princ "\nMust enter a number,")
)
)
)

Returns:

Command: (getnumber "\nEnter number: ")

Enter number: .25
0.25

Command: (getnumber "\nEnter number: ")

Enter number: 0.5636
0.5636

Command: (getnumber "\nEnter number: ")

Enter number: -.32
-0.32

Command: (getnumber "\nEnter number: ")

Enter number: 256
256

Command: (getnumber "\nEnter number: ")

Enter number: -200
-200

Command: (getnumber "\nEnter number: ")

Enter number: 3/4
0.75

Am i missing anything?

Jeff
 
Ken,

Sorry. I should have tested your function before I spoke. Knee-jerk reaction to seeing distof.

It seems to work fine. Moved initget into while function:

;; by Ken Alexander 1/29/2004
(defun getnum (/ a)
(while (not a)
(initget 128)
(setq a (getint "\nEnter a number: "))
(if (and a
(not (numberp a)))
(setq a (distof a))
)
)
a
)

Not sure what you mean by, "if a real is entered then a string is returned".

Command: (getnum)
Enter a number: 25.0
25.0

Command: (getnum)
Enter a number: .25
0.25

Command: (getnum)
Enter a number: -.25
-0.25

Command: (getnum)
Enter a number: 25
25

Command: (getnum)
Enter a number: 25A
Enter a number: 25
25

Perfect!

Many thanks,
Joe Burke
 
initget 128 allows for arbitrary input. If any thing but an integer is input to getint, getint returns a string.
 
Sorry, little quick on the send. Here is what I mean:

Command: (initget 128)
nil

Command: (getint)
25
25

Command: (initget 128)
nil

Command: (getint)
25.3
"25.3"
 
Ken,

I never would have thought of that. Good trick. :-)

Thanks again,
Joe
 
Thanks for your reply, Jeff. I haven't had a chance to try it yet.

Joe Burke

Jeff Mishler said:
Expanding on Tony's function:

(defun getnumber (msg / value result)
(while (not result)
(setq value (getstring msg))
(if (distof value)
(if (or (wcmatch value "*`.*")
(wcmatch value "*[/\]*")
)
(setq result (distof value))
(setq result (atoi value))
)
(princ "\nMust enter a number,")
)
)
)

Returns:

Command: (getnumber "\nEnter number: ")

Enter number: .25
0.25

Command: (getnumber "\nEnter number: ")

Enter number: 0.5636
0.5636

Command: (getnumber "\nEnter number: ")

Enter number: -.32
-0.32

Command: (getnumber "\nEnter number: ")

Enter number: 256
256

Command: (getnumber "\nEnter number: ")

Enter number: -200
-200

Command: (getnumber "\nEnter number: ")

Enter number: 3/4
0.75

Am i missing anything?

Jeff

Joe Burke said:
Tony,

If I pass .25 to your function, I get misplaced dot on input. I guess because:

Command: (read ".25")
; error: misplaced dot on input

Seems I can't use distof (Ken) because it returns a real when passed a string representing an integer. That and the misplaced dot error is what caused me to revisit this topic. It was discussed here in October of last year.

Thanks
Joe Burke

converting represent a
number,
 
Joe:

I thought your work was fine (er, except for the minus thing). But the better news is you stirred up some activity and can walk away with a better mouse trap!

Nice work, Jeff. I'm wondering if the code could be condensed just a tad and souped up a little bit to add in scientific notation plus evaluation of variables, including pi... (defun GetNumber (msg / value result) (while (not result) (setq value (getstring msg)) (cond ((numberp (setq result (eval (read value)))) result ) ((setq result (distof value)) (if (wcmatch value "*`.*,*[/\]*,*[eE]*") result (atoi value) ) ) (setq result (prompt "\nMust enter a number or numeric symbol,")) ) )
)

As to a value of "2'" apparently architectural units must be set, but that's better failing than having a crapload of conditions figuring (distof value (getvar "lunits")).
 
John Uhden said:
((numberp (setq result (eval (read value))))

Like I said, the use of read on user-entered strings,
without proper error handling is unsound.
 
(defun GetNumber (msg / value result)
(while (not result)
(setq value (getstring msg))
(if (= "." (substr value 1 1))
(setq value (strcat "0" value))
)
(cond
((numberp (setq result (eval (read value))))
result
)
((setq result (distof value))
(if (wcmatch value "*`.*,*[/\]*,*[eE]*")
result
(atoi value)
)
)
(setq result (prompt "\nMust enter a number or numeric symbol, ")) ) )
)

Comando: (GETNUMBER "Enter a number: ")
Enter a number: 0.1
0.1

Comando: (GETNUMBER "Enter a number: ")
Enter a number: .1
0.1

Comando: (GETNUMBER "Enter a number: ")
Enter a number: 1.0
1.0

Comando: (GETNUMBER "Enter a number: ")
Enter a number: 1'
1

Comando: (GETNUMBER "Enter a number: ")
Enter a number: .
0.0

Comando: (GETNUMBER "Enter a number: ")
Enter a number: 1
1

Comando: (GETNUMBER "Enter a number: ")
Enter a number: 0
0

Comando: (GETNUMBER "Enter a number: ")
Enter a number: 0.0
0.0

Comando: (GETNUMBER "Enter a number: ")
Enter a number: .0
0.0
 
Hi Herman,

Another one that doesn't work, which I thought might:

Command: (vl-princ-to-string .25)
; error: misplaced dot on input

The other thread on this topic started 9/17/2003. The subject was, "Is there any solution which can identify that a string is a number or character". So much for brevity. The fact read errors on ".25" was discussed there. Some solutions were offered, but I doubt they were comprehensive.

I think Ken's recent solution is elegant, if not brilliant. He contributed to the other thread, suggesting use of distof. Which worked fine until my incremented text string changed from "25" to "26.0".

For what it's worth, here's the function I was using. It's a hybrid of Ken's suggestion and your str2num function. BTW, I think there are other functions floating around the NG named "str2num" designed to do different things.

(defun IsNumber ( x )
(cond
((numberp x) x)
((= (type x) 'STR) (distof x 2)) ;of course returns 25.0 if string is "25" ((= (type x) 'SYM) (IsNumber (eval x))) ;recurse on evaluated arg )
)

Keeping in mind, it's one thing to test whether an argument is a number (T or nil). While another to return the argument in a useable fashion.

Joe Burke
 

Latest threads

Back
Top