Use of initialized value in pattern match

M

mike.wilson8

New at Perl and I'm sure this is a stupid mistake. I'm reading a txt
file and unfortunately the lines wrap so I'm reading the lines as
$firstline and $secondline doing a substr as well. I'm getting the
"Use of initialized value" error on ##problem line below and was
wondering if anyone can assist?

Thanks,
Mike



$filename = "C:/Documents and Settings/C150391/Desktop/PL.xls";
$path = "C:/Documents and Settings/C150391/Desktop/ORBIT SEARCH
RESULTS.txt";

open (MSG, "$path") || die "Cannot open $path\n";

while($firstline = <MSG>)
{
$secondline = <MSG>;

if ($firstline =~/JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC/)
{
$tktnum = substr ($line,3,8);
$userid = substr ($line,14,5);
$pri = substr ($line,29,1);
$status = substr ($line,38,4);
$type = substr ($line,48,12);
$opened = substr ($line,62,7);
$lastupdated = substr ($line,74,6);
}
if ($secondline =~ /\s+\d+\s+\d+\s+\d+/) ##problem line
{
$oplstupdated = substr ($secondline,9,3);
$lstupdated = substr ($secondline,25,3);
$opentoday = substr ($secondline,41,3);
}

}
 
P

Paul Lalli

New at Perl and I'm sure this is a stupid mistake. I'm reading a txt
file and unfortunately the lines wrap so I'm reading the lines as
$firstline and $secondline doing a substr as well. I'm getting the
"Use of initialized value" error

Just to be pedantic - that's a warning, not an error.
on ##problem line below and was
wondering if anyone can assist?

I have to assume you have warnings enabled, or you would not have
gotten that warning. However, you do not seem to have strict enabled.
Please do so, and in the future, please post a short but *complete*
script that demonstrates your error.
$filename = "C:/Documents and Settings/C150391/Desktop/PL.xls";
$path = "C:/Documents and Settings/C150391/Desktop/ORBIT SEARCH
RESULTS.txt";

Kudos to you for recognizing that windows has no problem with / as
directory separators.
open (MSG, "$path") || die "Cannot open $path\n";

1) Don't needlessly doublequote variables
2) Use the three-argument form of open
3) Use lexical filehandles, not global barewords
4) Tell the user *why* the file couldn't be opened.

open my $MSG, '<', $path or die "Cannot open '$path': $!\n";

while($firstline = <MSG>)
{
$secondline = <MSG>;

if ($firstline =~/JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC/)
{
$tktnum = substr ($line,3,8);
$userid = substr ($line,14,5);
$pri = substr ($line,29,1);
$status = substr ($line,38,4);
$type = substr ($line,48,12);
$opened = substr ($line,62,7);
$lastupdated = substr ($line,74,6);
}
if ($secondline =~ /\s+\d+\s+\d+\s+\d+/) ##problem line

If this line is giving you the warning you mentioned, it means that
$secondline is undefined. The way you assigned it, this means that you
had already reached the end of file at the assignment to $firstline,
and there was nothing left to put into $secondline. Are you sure that
*every* "line" of the file is wrapped into two actual lines? Further,
are you even sure that the lines are *really* wrapped, and it's not
just displaying that way in whatever text reader you're using?

After you assign to $firstline and $second line, try printing each of
them out:
print "First: $firstline\nSecond: $secondline\n\n";
and see if those are what you expect them to be.

Paul Lalli
 
N

niall.macpherson

if ($firstline =~/JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC/)
{
$tktnum = substr ($line,3,8);
$userid = substr ($line,14,5);
$pri = substr ($line,29,1);
$status = substr ($line,38,4);
$type = substr ($line,48,12);
$opened = substr ($line,62,7);
$lastupdated = substr ($line,74,6);
}

}

Are you familiar with unpack ?

If you are matching fixed size fields within a string you might find it
easer to use 'unpack' rather than substr.

(untested)

($tktnum, $userid, $pri, $status, $type, $opened, $lastupdated) =
unpack ( "x3 A8 x3 A5 x10 A1 x8 A4 x6 A12 x2 A7 x5 A6", $line);

This translates to
Ignore 3 bytes, grab 8 Alphanumeric bytes, Ignore 3 bytes, grab 5
Alphanumeric bytes,
Ignore 10 bytes, grab 1 Alphanumeric bytes, Ignore 8 bytes, grab 4
Alphanumeric bytes,
etc etc etc.

HTH
 
B

Brian McCauley

Are you familiar with unpack ?

Are you?
If you are matching fixed size fields within a string you might find it
easer to use 'unpack' rather than substr.

unpack() is great with byte strings. It's rather dodgy on character
strings. Obviously for pure ASCII data there's no difference.
(untested)

($tktnum, $userid, $pri, $status, $type, $opened, $lastupdated) =
unpack ( "x3 A8 x3 A5 x10 A1 x8 A4 x6 A12 x2 A7 x5 A6", $line);

This translates to
Ignore 3 bytes, grab 8 Alphanumeric bytes, Ignore 3 bytes, grab 5
Alphanumeric bytes,

You mean ASCII characters not Alphanumeric bytes.
Ignore 10 bytes, grab 1 Alphanumeric bytes, Ignore 8 bytes, grab 4
Alphanumeric bytes,
etc etc etc.

It should be noted that bytes and characters are not the same things
unless you are restricted to ASCII.
 
D

DJ Stunks

if ($firstline =~/JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC/)

I'm sure there's a better way to do this whole step, but at least that
regex can be fixed a bit:

C:\>perl -MRegex::preSuf -e
"$_='JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC'; \
print presuf( split /\|/ );"

(?:A(?:pR|UG)|DEC|FEB|J(?:AN|U[LN])|MA[RY]|NOV|OCT|SEP)

-jp
 
T

Tad McClellan

DJ Stunks said:
if ($firstline =~/JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC/)

but at least that
regex can be fixed a bit:

(?:A(?:pR|UG)|DEC|FEB|J(?:AN|U[LN])|MA[RY]|NOV|OCT|SEP)


You should put in a smiley when you make a joke post like this.

IMO, you have made it much much worse than it was.
 
B

Ben Morrow

Quoth (e-mail address removed):
DJ Stunks said:
if ($firstline =~/JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC/)

but at least that
regex can be fixed a bit:

(?:A(?:pR|UG)|DEC|FEB|J(?:AN|U[LN])|MA[RY]|NOV|OCT|SEP)


You should put in a smiley when you make a joke post like this.

IMO, you have made it much much worse than it was.

And I would always use something like

my $month =
map qr/$_/,
join '|',
map quotemeta,
qw/JAN FEB ... DEC/;

just because then you can get the list from somewhere else (l10n, maybe)
later, if you need to.

Ben
 
A

Anno Siegel

[...]
And I would always use something like

my $month =
map qr/$_/,
join '|',
map quotemeta,
qw/JAN FEB ... DEC/;

just because then you can get the list from somewhere else (l10n, maybe)
later, if you need to.

The one-shot map is nice, but it needs list context:

my ( $month) =
map qr/$_/,
join '|',
map quotemeta,
qw/JAN FEB ... DEC/;

Alternatively,

$month = qr/$_/ for
join '|',
map quotemeta,
qw/JAN FEB ... DEC/;

Can't have enough tricks to smuggle a computed expression inside a qr//.

Anno
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top