Home > Archive > PERL Beginners > April 2004 > illegal octal digit '8'?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
illegal octal digit '8'?
|
|
| Charlotte Hee 2004-04-02, 8:31 pm |
|
In my perl script I use the unix command 'date' to make a time stamp
because eventually I want the date format to be DD-MON-YYYY, where DD is
the number of the day (1-31), MON is the 3-char spelling of month (i.e.
JAN), and YYYY is the 4-digit year. In this perl script I'm just testing
for the date so the day and year aren't in this script.
The date command returns the month as a two digit number which I pass to
my routine. My routine then changes the two digit number into the
corresponding 3-char letters for that month. I get an error message like
Illegal octal digit '8'
Illegal octal digit '9'
when my routine uses the number 08 and 09. I don't understand what
this error means. If I change my routine to use 8 and 9 I don't see this
error message. The number for April is 04 and that doesn't seem to cause a
problem. What is special about numbers 08 and 09?
Here is the code: ( thanks, Chee )
#!/usr/local/bin/perl -w
#
use strict;
use vars qw($mm $mon);
$mm = `date +%m`;
$mon = &convertMO($mm);
print "month is $mon\n";
exit;
sub convertMO {
my ($tmp) = @_;
my $xmon;
if ( $tmp == 01 ){ $xmon = 'JAN'; }
if ( $tmp == 02 ){ $xmon = 'FEB'; }
if ( $tmp == 03 ){ $xmon = 'MAR'; }
if ( $tmp == 04 ){ $xmon = 'APR'; }
if ( $tmp == 05 ){ $xmon = 'MAY'; }
if ( $tmp == 06 ){ $xmon = 'JUN'; }
if ( $tmp == 07 ){ $xmon = 'JUL'; }
if ( $tmp == 08 ){ $xmon = 'AUG'; } #<-- illegal error
if ( $tmp == 09 ){ $xmon = 'SEP'; } #<-- illegal error
if ( $tmp == 10 ){ $xmon = 'OCT'; }
if ( $tmp == 11 ){ $xmon = 'NOV'; }
if ( $tmp == 12 ){ $xmon = 'DEC'; }
return $xmon;
}
| |
| Paul Johnson 2004-04-02, 9:30 pm |
| On Fri, Apr 02, 2004 at 04:44:48PM -0800, Charlotte Hee wrote:
>
>
> In my perl script I use the unix command 'date' to make a time stamp
> because eventually I want the date format to be DD-MON-YYYY, where DD is
> the number of the day (1-31), MON is the 3-char spelling of month (i.e.
> JAN), and YYYY is the 4-digit year. In this perl script I'm just testing
> for the date so the day and year aren't in this script.
> The date command returns the month as a two digit number which I pass to
> my routine. My routine then changes the two digit number into the
> corresponding 3-char letters for that month. I get an error message like
>
> Illegal octal digit '8'
> Illegal octal digit '9'
>
> when my routine uses the number 08 and 09. I don't understand what
> this error means. If I change my routine to use 8 and 9 I don't see this
> error message. The number for April is 04 and that doesn't seem to cause a
> problem. What is special about numbers 08 and 09?
Numbers starting with a zero are interpreted as octal numbers. The
digits 8 and 9 are illegal in octal numbers.
perldoc perldata
> Here is the code: ( thanks, Chee )
>
>
> #!/usr/local/bin/perl -w
> #
>
> use strict;
> use vars qw($mm $mon);
>
> $mm = `date +%m`;
> $mon = &convertMO($mm);
>
> print "month is $mon\n";
>
> exit;
>
> sub convertMO {
> my ($tmp) = @_;
> my $xmon;
>
> if ( $tmp == 01 ){ $xmon = 'JAN'; }
> if ( $tmp == 02 ){ $xmon = 'FEB'; }
> if ( $tmp == 03 ){ $xmon = 'MAR'; }
> if ( $tmp == 04 ){ $xmon = 'APR'; }
> if ( $tmp == 05 ){ $xmon = 'MAY'; }
> if ( $tmp == 06 ){ $xmon = 'JUN'; }
> if ( $tmp == 07 ){ $xmon = 'JUL'; }
> if ( $tmp == 08 ){ $xmon = 'AUG'; } #<-- illegal error
> if ( $tmp == 09 ){ $xmon = 'SEP'; } #<-- illegal error
> if ( $tmp == 10 ){ $xmon = 'OCT'; }
> if ( $tmp == 11 ){ $xmon = 'NOV'; }
> if ( $tmp == 12 ){ $xmon = 'DEC'; }
>
> return $xmon;
> }
Here is code which does the same in a slightly more perlish manner:
#!/usr/bin/perl
use warnings;
use strict;
{
my @months = qw( JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC );
sub month_to_string { $months[shift] }
}
my $month_numeric = (localtime)[4];
my $month_string = month_to_string $month_numeric;
print "month is $month_string\n";
--
Paul Johnson - paul@pjcj.net
http://www.pjcj.net
| |
| Wiggins D'Anconia 2004-04-02, 9:30 pm |
| Charlotte Hee wrote:
>
> In my perl script I use the unix command 'date' to make a time stamp
> because eventually I want the date format to be DD-MON-YYYY, where DD is
> the number of the day (1-31), MON is the 3-char spelling of month (i.e.
> JAN), and YYYY is the 4-digit year. In this perl script I'm just testing
> for the date so the day and year aren't in this script.
> The date command returns the month as a two digit number which I pass to
> my routine. My routine then changes the two digit number into the
> corresponding 3-char letters for that month. I get an error message like
>
> Illegal octal digit '8'
> Illegal octal digit '9'
>
> when my routine uses the number 08 and 09. I don't understand what
> this error means. If I change my routine to use 8 and 9 I don't see this
> error message. The number for April is 04 and that doesn't seem to cause a
> problem. What is special about numbers 08 and 09?
>
In general this is a bad way of going about all of this, but we will get
to that in a moment...
> Here is the code: ( thanks, Chee )
>
>
> #!/usr/local/bin/perl -w
> #
>
> use strict;
A good start...
> use vars qw($mm $mon);
>
perldoc -f our 'use vars is a bit dated, unless you know why to use them
or have an older Perl, stick to 'our'. Having said that do they need to
be package variables in the 'main' namespace? Better to make them
lexically scoped with 'my'
perldoc -f my
> $mm = `date +%m`;
There is no reason to shell out to get the date components *especially*
if you aren't going to use full paths, chomp the output, check for error
codes, etc.
perldoc -f localtime
> $mon = &convertMO($mm);
>
Drop the & until you know why you don't.
> print "month is $mon\n";
>
> exit;
>
> sub convertMO {
> my ($tmp) = @_;
> my $xmon;
>
> if ( $tmp == 01 ){ $xmon = 'JAN'; }
> if ( $tmp == 02 ){ $xmon = 'FEB'; }
> if ( $tmp == 03 ){ $xmon = 'MAR'; }
> if ( $tmp == 04 ){ $xmon = 'APR'; }
> if ( $tmp == 05 ){ $xmon = 'MAY'; }
> if ( $tmp == 06 ){ $xmon = 'JUN'; }
> if ( $tmp == 07 ){ $xmon = 'JUL'; }
> if ( $tmp == 08 ){ $xmon = 'AUG'; } #<-- illegal error
> if ( $tmp == 09 ){ $xmon = 'SEP'; } #<-- illegal error
Since you are using the numerical comparison on numbers that start with
a '0' which Perl takes to mean as numbers in octal rather than decimal.
As soon as you hit 8 and 9 the digits are not expected in an octal
number. You would be better off using string comparison, or dispensing
with this subrouine anyways. It would be much simpler and faster to
store the month abbreviations in a hash and index into that hash using a
key, better still use an array since it is already ordered with numbered
indexes.
> if ( $tmp == 10 ){ $xmon = 'OCT'; }
> if ( $tmp == 11 ){ $xmon = 'NOV'; }
> if ( $tmp == 12 ){ $xmon = 'DEC'; }
>
> return $xmon;
> }
>
So a Perlish way to do this,
my (@months) =
('jan','feb','mar','apr','may','jun','ju
l','aug','sep','oct','nov','dec');
my ($mday, $mon, $year) = (localtime)[3,4,5];
my $date = sprintf('%02d-%3s-%04d', uc $mday, $months[$mon] , $year+1900);
print "Date: $date\n";
perldoc -f uc
perldoc -f sprintf
HTH,
http://danconia.org
| |
| John W. Krahn 2004-04-02, 9:30 pm |
| Wiggins D'Anconia wrote:
>
> So a Perlish way to do this,
>
> my (@months) =
> ('jan','feb','mar','apr','may','jun','ju
l','aug','sep','oct','nov','dec');
> my ($mday, $mon, $year) = (localtime)[3,4,5];
>
> my $date = sprintf('%02d-%3s-%04d', uc $mday, $months[$mon] , $year+1900);
^^^^^^^^
You are upper-casing the number in $mday instead of the month name in
$months[$mon]. :-)
my $date = sprintf '%02d-%3s-%04d', $mday, uc $months[ $mon ], $year +
1900;
> print "Date: $date\n";
>
> perldoc -f uc
> perldoc -f sprintf
John
--
use Perl;
program
fulfillment
| |
| Tim Johnson 2004-04-02, 10:30 pm |
|
Just another suggestion on how you might accomplish the same thing:=20
######################################
my @months =3D qw(XXX JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC);
return $months[$tmp]
######################################
-----Original Message-----
From: Charlotte Hee [mailto:chee@slac.stanford.edu]=20
Sent: Friday, April 02, 2004 4:45 PM
To: beginners@perl.org
Subject: illegal octal digit '8'?
<snip>
if ( $tmp =3D=3D 01 ){ $xmon =3D 'JAN'; }
if ( $tmp =3D=3D 02 ){ $xmon =3D 'FEB'; }
if ( $tmp =3D=3D 03 ){ $xmon =3D 'MAR'; }
if ( $tmp =3D=3D 04 ){ $xmon =3D 'APR'; }
if ( $tmp =3D=3D 05 ){ $xmon =3D 'MAY'; }
if ( $tmp =3D=3D 06 ){ $xmon =3D 'JUN'; }
if ( $tmp =3D=3D 07 ){ $xmon =3D 'JUL'; }
if ( $tmp =3D=3D 08 ){ $xmon =3D 'AUG'; } #<-- illegal error
if ( $tmp =3D=3D 09 ){ $xmon =3D 'SEP'; } #<-- illegal error
if ( $tmp =3D=3D 10 ){ $xmon =3D 'OCT'; }
if ( $tmp =3D=3D 11 ){ $xmon =3D 'NOV'; }
if ( $tmp =3D=3D 12 ){ $xmon =3D 'DEC'; }
}
return $xmon;
| |
| Wiggins D'Anconia 2004-04-02, 10:30 pm |
| John W. Krahn wrote:
> Wiggins D'Anconia wrote:
>
>
> ^^^^^^^^
> You are upper-casing the number in $mday instead of the month name in
> $months[$mon]. :-)
>
> my $date = sprintf '%02d-%3s-%04d', $mday, uc $months[ $mon ], $year +
> 1900;
That's what I get for working in two different windows on a laptop, good
catch....
http://danconia.org
| |
| Charlotte Hee 2004-04-06, 1:32 pm |
|
Thank you. I will study this more perlish style and upgrade my
program. Chee
On Fri, 2 Apr 2004, Wiggins d'Anconia wrote:
> Date: Fri, 02 Apr 2004 20:21:11 -0500
> From: Wiggins d'Anconia <wiggins@danconia.org>
> To: Charlotte Hee <chee@SLAC.Stanford.EDU>
> Cc: beginners@perl.org
> Subject: Re: illegal octal digit '8'?
>
> Charlotte Hee wrote:
>
> In general this is a bad way of going about all of this, but we will get
> to that in a moment...
>
>
>
> A good start...
>
>
> perldoc -f our 'use vars is a bit dated, unless you know why to use them
> or have an older Perl, stick to 'our'. Having said that do they need to
> be package variables in the 'main' namespace? Better to make them
> lexically scoped with 'my'
>
> perldoc -f my
>
>
> There is no reason to shell out to get the date components *especially*
> if you aren't going to use full paths, chomp the output, check for error
> codes, etc.
>
> perldoc -f localtime
>
>
> Drop the & until you know why you don't.
>
>
> Since you are using the numerical comparison on numbers that start with
> a '0' which Perl takes to mean as numbers in octal rather than decimal.
> As soon as you hit 8 and 9 the digits are not expected in an octal
> number. You would be better off using string comparison, or dispensing
> with this subrouine anyways. It would be much simpler and faster to
> store the month abbreviations in a hash and index into that hash using a
> key, better still use an array since it is already ordered with numbered
> indexes.
>
>
>
>
> So a Perlish way to do this,
>
> my (@months) =
> ('jan','feb','mar','apr','may','jun','ju
l','aug','sep','oct','nov','dec');
> my ($mday, $mon, $year) = (localtime)[3,4,5];
>
> my $date = sprintf('%02d-%3s-%04d', uc $mday, $months[$mon] , $year+1900);
>
> print "Date: $date\n";
>
> perldoc -f uc
> perldoc -f sprintf
>
> HTH,
>
> http://danconia.org
>
|
|
|
|
|