http://qs321.pair.com?node_id=19662

vnpandey has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I want your help for a minor querry!!! In the perl programme I want to get some input (numeric) from the user. After that I store in in $a Now how should I check whether the input is a number or not... for ex. it may be like 987fsfh{ etc . One way which I could think of is to chop the $a till it becomes empty & see that the all characters return when chopping match between digits from 0 to 9 with one of them can be . but is there a smarter way out as it is very redundant & long way of doing it... Thanks, VNPAndey

Replies are listed 'Best First'.
Re: Minor querry!!
by plaid (Chaplain) on Jun 24, 2000 at 00:40 UTC
    You probably want something like:
    if($a =~ /\D/) { # Not a number }
    The /D matches non-digits, so this will be true if $a contains any non-digits.
Re: Minor querry!!
by Shendal (Hermit) on Jun 24, 2000 at 00:40 UTC
    I think you want something like this:
    use strict; use warnings; my($a) = <STDIN>; chomp($a); if ($a !~ /^\d+$/) { print "Sorry - you didn't give me a number.\n"; exit 1; } else { print "Yay! That's a number!\n"; }
    Hope that helps,
    Shendal
      Another variation on Shendal's solution could be to allow for decimals. I hardly ever work with whole numbers (not through choice, but because of the data we are responsible for here).
      my $number = <STDIN>; chomp $number; if ($number !~ /^\d+\.?\d*$/) { print "$number is not a number.\n"; exit 1; } else { print "$number is a number!\n"; }
      I hope this proves useful to someone. mrmick
RE: Minor querry!!
by sean (Beadle) on Jun 24, 2000 at 04:51 UTC
    Another way:
    if ($a eq $a+0) { #$a is a decimal number }
    This won't work if you were planning on accepting input numbers in hex or octal though, only decimal.
Re: Minor querry!!
by Adam (Vicar) on Jun 24, 2000 at 00:40 UTC
    Use a regex:
    if( $input =~ /^(\d+)$/ ) { $a = $1; } else { print "Please enter a number\n" }
    or something like that.
Re: Minor query
by spudzeppelin (Pilgrim) on Jun 24, 2000 at 01:00 UTC

    Or, supposing you want to allow decimals:

    FOO: $a = <STDIN>; chomp($a); $a =~ tr/0-9.//cd; if (length($a) < 1) { print "Please enter a number\n"; goto FOO; }

    Spud Zeppelin * spud@spudzeppelin.com

      While your example using tr/// is interesting, the use of the g-word (goto) is a bad idea. Instead, use a loop:
      while (!$stop) { $a = <STDIN>; chomp($a); $a =~ tr/0-9.//cd; if (length($a) < 1) { print "Please enter a number\n"; $stop = 1; } }
      Of course, I think the other examples, especially plaid's suggestion are less obfuscated.
        a slightly nicer fusion of your two methods is the following:
        PROMPT: { chomp($a = <STDIN>); $a =~ tr/0-9.//cd; unless (length($a)) { print "Please enter a number\n"; redo PROMPT; } }

        All these loops are so long! Labels and status variables and chomping, oh my!

        How about this:

        { print "Number?\n"; redo unless <STDIN> =~ /^\d+$/; }

        Or, to save the value (which can be useful :)

        { print "Number?\n"; redo unless <STDIN> =~ /^(\d+)$/ and $number=$1; }

        But my personal favorite would be simply:

        print "Number?\n" while <STDIN> !~ /^\d+$/;

        I beg to differ. "Never, never, never use goto!" is one of those programming mantras which are taught to beginners because at that level, the temptation is to use it where it is not appropriate. However, as a developer becomes more experienced, the usefulness, clarity, and simplicity of an unencumbered "jump over there" instruction make it more valuable when used sparingly and appropriately. And in this case, an exception handler of a sort that basically says "go back three lines and try it again," the use is very appropriate.

        While we are drifing dangerously offtopic, I am going to ask you to reconsider the two snippets above, and tell me which is actually more readable -- the one that obfuscates a goto with a while loop, or the one that explicity uses the goto when the goto is EXACTLY the instruction being used in both, algorithmically.

        Spud Zeppelin * spud@spudzeppelin.com