Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Numeric or character ?

Reply
Thread Tools

Numeric or character ?

 
 
John Cecere
Guest
Posts: n/a
 
      07-19-2005
Since

if ("aaa" == 0) {
print "true\n";
}

will print true, how does one go about testing a value as an integer. For example, the user enters data:

$a=<STDIN>;

The user might accidentally type in character data, but I need to perform a test to see if what they entered is a number between 0
and 255, and return a bad status for anything else. Doing this:

if ($a < 0 || $a > 255)

won't catch character data.

What's the _simple_ way of doing this ?

Thanks,
John Cecere
 
Reply With Quote
 
 
 
 
A. Sinan Unur
Guest
Posts: n/a
 
      07-19-2005
John Cecere <(E-Mail Removed)> wrote in
news:dbjr71$4bn$(E-Mail Removed):

> Since
>
> if ("aaa" == 0) {
> print "true\n";
> }
>
> will print true, how does one go about testing a value as an integer.
> For example, the user enters data:
>
> $a=<STDIN>;
>
> The user might accidentally type in character data,


You seem to be unaware that everything that is stored in $a
at this point is *character* data. If the user enters 110,
$a will contain the string consisting of the characters '1',
'1', and '0', not the integer 110.

> need to perform a test to see if what they entered is a number
> between 0 and 255, and return a bad status for anything else.
> Doing this:
>
> if ($a < 0 || $a > 255)


Of course not, you have a string in $a and you are comparing it
to a number, and therefore it is subject to all the conditions of
number to string conversion in Perl.

BTW, the variables $a and $b are special in Perl
(see perldoc -f sort). You should not use them willy-nilly.

> What's the _simple_ way of doing this ?


In general, one checks if input conforms to a certain format by
using an appropriate regex match. In this case, it is a very
simple one:

#!/usr/bin/perl

use strict;
use warnings;

my $input;

$| = 1;

do {
print "Please enter and integer between 0 and 255: ";
$input = <STDIN>;
} until $input =~ /^(\d\d?\d?)$/ and 0 + $1 < 256;

print "You entered: $input\n";

__END__

For more general numeric formats, see

<URL:http://search.cpan.org/~abigail/Regexp-Common-2.120/lib/Regexp/Common/number.pm>

Sinan

--
A. Sinan Unur <(E-Mail Removed)>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html
 
Reply With Quote
 
 
 
 
A. Sinan Unur
Guest
Posts: n/a
 
      07-19-2005
Abigail <(E-Mail Removed)> wrote in
news:(E-Mail Removed):

> A. Sinan Unur ((E-Mail Removed)) wrote on MMMMCCCXL September
> MCMXCIII in <URL:news:Xns9698B4F254690asu1cornelledu@127.0.0.1 >:
> //
> // BTW, the variables $a and $b are special in Perl
> // (see perldoc -f sort). You should not use them willy-nilly.
>
> I use $a and $b willy-nilly all the time, and I have never ran into
> trouble. While it is possible to create code that might do something
> unexpected, it takes a bit of an effort to do so.


True, but I have a knack for unintentionally discovering the complicated
steps to produce unlikely scenarios while doing somthing completely
mundane.

Sinan

--
A. Sinan Unur <(E-Mail Removed)>
(reverse each component and remove .invalid for email address)

comp.lang.perl.misc guidelines on the WWW:
http://mail.augustmail.com/~tadmc/cl...uidelines.html
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      07-20-2005
John Cecere wrote:
> Since
>
> if ("aaa" == 0) {
> print "true\n";
> }
>
> will print true, how does one go about testing a value as an integer.
> For example, the user enters data:
> $a=<STDIN>;
>
> The user might accidentally type in character data,


Well, I hope he does. How could he type anything that is not a character?

> but I need to
> perform a test to see if what they entered is a number between 0 and
> 255, and return a bad status for anything else.


First of all I suggest to get your terminology right. The user enters a
sequence of characters. You want to restrict this to digits. And then Perl
can interpret a sequence of digits as a number. While this might seem to be
nitpicking it actually helps immensely to partition your problem in the
right way.

Having said that, is there anything wrong with the answer given in the FAQ?
perldoc -q number:
"How do I determine whether a scalar is a number/whole/integer/float?"

> Doing this:
> if ($a < 0 || $a > 255)
>
> won't catch character data.


By some definiton of "character" which has nothing to do with the standard
definition of character.
Of course it doesn't because you are comparing the numerical value of a
scalar. If you want to test the characters of string (yes, even digits are
characters) then use a function that uses strings or characters, e.g.
pattern matching or substr or pos or similar.

> What's the _simple_ way of doing this ?


Maybe the way as suggested in the FAQ?

jue


 
Reply With Quote
 
Sven-Thorsten Fahrbach
Guest
Posts: n/a
 
      07-26-2005
> In general, one checks if input conforms to a certain format by
> using an appropriate regex match. In this case, it is a very
> simple one:
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> my $input;
>
> $| = 1;


I'm just being interested: is there any specific reason why you make output unbuffered here? I think it's not necessary for this script but maybe something has escaped me...

>
> do {
> print "Please enter and integer between 0 and 255: ";
> $input = <STDIN>;
> } until $input =~ /^(\d\d?\d?)$/ and 0 + $1 < 256;
>
> print "You entered: $input\n";

 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      07-27-2005
Sven-Thorsten Fahrbach <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> > In general, one checks if input conforms to a certain format by
> > using an appropriate regex match. In this case, it is a very
> > simple one:
> >
> > #!/usr/bin/perl
> >
> > use strict;
> > use warnings;
> >
> > my $input;
> >
> > $| = 1;

>
> I'm just being interested: is there any specific reason why you make
> output unbuffered here? I think it's not necessary for this script but
> maybe something has escaped me...


Autoflushing (which is more to the point than "unbuffered") isn't
exactly needed here, but it's convenient to have. Its main purpose
is to match the flushing behavior of STDOUT and STDERR so that messages
on both appear on the screen when they are printed, not when a buffer
happens to overflow. Otherwise, error messages and normal output may
appear out of sequence, which can be confusing.

I put "$| = 1" in all my scripts (not modules), and only take it out
when the script happens to do mass IO via STDOUT (as in a filter).

Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
Reply With Quote
 
Sven-Thorsten Fahrbach
Guest
Posts: n/a
 
      07-27-2005
On 27 Jul 2005 10:00:22 GMT
http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de (Anno Siegel) wrote:

> Sven-Thorsten Fahrbach <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> > > In general, one checks if input conforms to a certain format by
> > > using an appropriate regex match. In this case, it is a very
> > > simple one:
> > >
> > > #!/usr/bin/perl
> > >
> > > use strict;
> > > use warnings;
> > >
> > > my $input;
> > >
> > > $| = 1;

> >
> > I'm just being interested: is there any specific reason why you make
> > output unbuffered here? I think it's not necessary for this script but
> > maybe something has escaped me...

>
> Autoflushing (which is more to the point than "unbuffered") isn't
> exactly needed here, but it's convenient to have. Its main purpose
> is to match the flushing behavior of STDOUT and STDERR so that messages
> on both appear on the screen when they are printed, not when a buffer
> happens to overflow. Otherwise, error messages and normal output may
> appear out of sequence, which can be confusing.
>
> I put "$| = 1" in all my scripts (not modules), and only take it out
> when the script happens to do mass IO via STDOUT (as in a filter).


Okay, I know what it does, I just wasn't aware that this was kind of a custom among some programmers. When I need unbuffered output I let it go to STDERR usually which is unbuffered (or autoflushed if you prefer) by default.
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      07-27-2005
Sven-Thorsten Fahrbach <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> On 27 Jul 2005 10:00:22 GMT
> (E-Mail Removed)-berlin.de (Anno Siegel) wrote:
>
> > Sven-Thorsten Fahrbach <(E-Mail Removed)> wrote in

> comp.lang.perl.misc:


[...]

> > > I'm just being interested: is there any specific reason why you make
> > > output unbuffered here? I think it's not necessary for this script but
> > > maybe something has escaped me...

> >
> > Autoflushing (which is more to the point than "unbuffered") isn't
> > exactly needed here, but it's convenient to have. Its main purpose
> > is to match the flushing behavior of STDOUT and STDERR so that messages
> > on both appear on the screen when they are printed, not when a buffer
> > happens to overflow. Otherwise, error messages and normal output may
> > appear out of sequence, which can be confusing.
> >
> > I put "$| = 1" in all my scripts (not modules), and only take it out
> > when the script happens to do mass IO via STDOUT (as in a filter).

>
> Okay, I know what it does, I just wasn't aware that this was kind of a
> custom among some programmers. When I need unbuffered output I let it go
> to STDERR usually which is unbuffered (or autoflushed if you prefer) by
> default.


It's not just preference. An autoflushed IO channel is still buffered,
the buffer just doesn't fill up so much. A truly unbuffered channel
would be very hard to use.

Otherwise, the purpose of "$| = 1" isn't that we want STDOUT autoflushed,
it's that there already *is* autoflushed output that merges with it,
and the merging is smoother when both are autoflushed.

The problem is often not visible when printing directly to the terminal,
because terminal output is usually line buffered (another form of automatic
flushing). When the output goes to a file or pipe, to "| more" for
instance, the difference becomes apparent. Watch this:

[anno4000@lublin ~/clpm]$ cat script
#!/usr/bin/perl
use strict; use warnings;

$| = shift || 0;

print "one\n";
warn "two\n";
print "three\n";

[anno4000@lublin ~/clpm]$ ./script |& more
two
one
three

4000@lublin ~/clpm]$ ./script 1 |& more
one
two
three

Only in the second (autoflushed) example does the output appear in
the sequence it is produced. That is the problem "$| = 1" avoids.

Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
Reply With Quote
 
Sven-Thorsten Fahrbach
Guest
Posts: n/a
 
      07-27-2005
On 27 Jul 2005 11:56:27 GMT
(E-Mail Removed)-berlin.de (Anno Siegel) wrote:
> It's not just preference. An autoflushed IO channel is still buffered,
> the buffer just doesn't fill up so much. A truly unbuffered channel
> would be very hard to use.
>
> Otherwise, the purpose of "$| = 1" isn't that we want STDOUT autoflushed,
> it's that there already *is* autoflushed output that merges with it,
> and the merging is smoother when both are autoflushed.
>
> The problem is often not visible when printing directly to the terminal,
> because terminal output is usually line buffered (another form of automatic
> flushing). When the output goes to a file or pipe, to "| more" for
> instance, the difference becomes apparent. Watch this:
>
> [anno4000@lublin ~/clpm]$ cat script
> #!/usr/bin/perl
> use strict; use warnings;
>
> $| = shift || 0;
>
> print "one\n";
> warn "two\n";
> print "three\n";
>
> [anno4000@lublin ~/clpm]$ ./script |& more
> two
> one
> three
>
> 4000@lublin ~/clpm]$ ./script 1 |& more
> one
> two
> three
>
> Only in the second (autoflushed) example does the output appear in
> the sequence it is produced. That is the problem "$| = 1" avoids.


All right, that was enlightening, though I would not consider it a 'problem' exactly. If I come across a situation where non-autoflushed output might not be desireable, I print to STDERR or set $| = 1. I don't come from a profound C background, though, so I might be a little ignorant .
Excerpt from the Camel Book: 'Contrary to popular belief, setting this [$|] variable does not turn off buffering.'
Okey, my bad.

SveTho
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      07-27-2005
Sven-Thorsten Fahrbach <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> On 27 Jul 2005 11:56:27 GMT
> (E-Mail Removed)-berlin.de (Anno Siegel) wrote:


[Why do some set $| = 1 routinely? Demo how STDOUT and STDERR get out
of sequence if you don't]

> All right, that was enlightening, though I would not consider it a
> 'problem' exactly. If I come across a situation where non-autoflushed
> output might not be desireable, I print to STDERR or set $| = 1.


Sure, like everyone. The question was, why do it routinely. When working
on a program you don't want to see, say, the error message it died with
in front of material it has produced before it died.

There are other reasons to use it. If you want to watch a program's
file output through "tail -f ...", it will look jerky unless autoflushed.
Also, if you do an improvised user dialog through STDOUT and STDIN,
users may not see your prompt on some systems unless you autoflush
STDOUT. So it also makes a program more portable. Under normal
circumstances it doesn't hurt much. The exception is mass output
which becomes inefficient. It's the only reason I can think of to
turn it off.

Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Obtaining a Character value from a Unicode (numeric) value david Java 7 10-10-2012 02:38 PM
Decimal vs. hex for numeric character references Harlan Messinger HTML 2 11-19-2007 04:20 PM
int to numeric numeric(18,2) ? jobs ASP .Net 2 07-22-2007 12:32 AM
Arithmetic overflow error converting numeric to data type numeric. darrel ASP .Net 4 07-19-2007 09:57 PM
check if string contains numeric, and check string length of numeric value ief@specialfruit.be C++ 5 06-30-2005 01:08 PM



Advertisments