dealing with "error: misplaced dot on input"

Discussion in 'AutoCAD' started by Joe Burke, Jan 29, 2004.

  1. Joe Burke

    Joe Burke Guest

    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
     
    Joe Burke, Jan 29, 2004
    #1
  2. Joe Burke

    John Uhden Guest

    Pretty good, Joe!

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

    Actually, you might want to address "-.5"
     
    John Uhden, Jan 29, 2004
    #2
  3. Joe Burke

    Joe Burke Guest

    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 Burke, Jan 29, 2004
    #3
  4. 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
    )
    --
    Ken Alexander
    Acad2004
    Windows2000 Prof.

    "We can't solve problems by using the same kind
    of thinking we used when we created them."
    --Albert Einstein
     
    Ken Alexander, Jan 29, 2004
    #4
  5. Just thought of something...(initget 128) needs to be inside the
    while loop.

    --
    Ken Alexander
    Acad2004
    Windows2000 Prof.

    "We can't solve problems by using the same kind
    of thinking we used when we created them."
    --Albert Einstein
     
    Ken Alexander, Jan 29, 2004
    #5
  6. 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 Tanzillo, Jan 29, 2004
    #6
  7. Joe Burke

    Joe Burke Guest

    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 Burke, Jan 29, 2004
    #7
  8. 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.
    --
    Ken Alexander
    Acad2004
    Windows2000 Prof.

    "We can't solve problems by using the same kind
    of thinking we used when we created them."
    --Albert Einstein
     
    Ken Alexander, Jan 29, 2004
    #8
  9. Joe Burke

    Joe Burke Guest

    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
     
    Joe Burke, Jan 29, 2004
    #9
  10. Joe Burke

    Jeff Mishler Guest

    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
     
    Jeff Mishler, Jan 29, 2004
    #10
  11. Joe Burke

    Joe Burke Guest

    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
     
    Joe Burke, Jan 29, 2004
    #11
  12. initget 128 allows for arbitrary input. If any thing but an integer
    is input to getint, getint returns a string.
    --
    Ken Alexander
    Acad2004
    Windows2000 Prof.

    "We can't solve problems by using the same kind
    of thinking we used when we created them."
    --Albert Einstein
     
    Ken Alexander, Jan 29, 2004
    #12
  13. 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 Alexander
    Acad2004
    Windows2000 Prof.

    "We can't solve problems by using the same kind
    of thinking we used when we created them."
    --Albert Einstein
     
    Ken Alexander, Jan 29, 2004
    #13
  14. Joe Burke

    Joe Burke Guest

    Ken,

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

    Thanks again,
    Joe
     
    Joe Burke, Jan 30, 2004
    #14
  15. Thanks Joe, and you're welcome.

     
    Ken Alexander, Jan 30, 2004
    #15
  16. Joe Burke

    Joe Burke Guest

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

    Joe Burke

     
    Joe Burke, Jan 30, 2004
    #16
  17. Joe Burke

    John Uhden Guest

    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, Jan 30, 2004
    #17
  18. Like I said, the use of read on user-entered strings,
    without proper error handling is unsound.
     
    Tony Tanzillo, Jan 30, 2004
    #18
  19. (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

    --
     
    Marc'Antonio Alessi, Jan 30, 2004
    #19
  20. Joe Burke

    Joe Burke Guest

    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
     
    Joe Burke, Jan 30, 2004
    #20
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.