Newbie. Use of uninitialized value in print??

J

Jon Anderson

Hi,

Im having problems getting some Perl code to work (im a programming
newbie). The aim of the code is to read certain text from a file,
print it to screen then allow the user to make a choice based on that
output. Well, that's the aim so far anyway (im about half way through
the code). Ive been stuck on this however. Im getting the error "Use
of uninitialized value in print at... line 26, <STDIN> line 1."
Ive spent most of the day trying to work out what's wrong, but have
come up empty handed. The code is,

$lnum = 0;
open (INPUT, "file.txt") or die "Error, can't find file\n";
@raw_data=<INPUT>;
close(INPUT);
#Print to screen the pricelist in the text file
foreach $price (@raw_data)
{
@pricelist = split (/:/, $price);
print "$lnum" . " " . "$pricelist[1]\n" if @pricelist != 1;
$lnum ++;
}
print "\n";
$prices2 = @raw_data;
@prices1to5 = split (/:/, $prices2);
print "Please enter the item to be purchased..\n\n";
chomp($selectitem = <STDIN>);
if($selectitem == 1)
{
print "\n";
print "You selected item 1, which sells for\n";
print $prices1to5[1];
$item = 1;
}
elsif($selectitem == 2)
{
print "\n";
print "You selected item 2, which sells for\n";
print $prices1to5[2];
$item = 2;
}
elsif($selectitem == 3)
{
print "\n";
print "You selected item 3, which sells for\n";
print $prices1to5[3];
$item = 3;
}
elsif($selectitem == 4)
{
print "\n";
print "You selected item 4, which sells for\n";
print $prices1to5[4];
$item = 4;
}
elsif($selectitem == 5)
{
print "\n";
print "You selected item 5, which sells for\n";
print $prices1to5[5];
$item = 5;
}
else
{
print "\n";
print "Invalid item selection! No such item\n";
}


---

The code at line 26 is

18 $prices2 = @raw_data;
19 @prices1to5 = split (/:/, $prices2);
20 print "Please enter the item to be purchased..\n\n";
21 chomp($selectitem = <STDIN>);
22 if($selectitem == 1)
23 {
24 print "\n";
25 print "You selected item 1, which sells for\n";
26 print $prices1to5[1];
 
B

Brian McCauley

Jon said:
Im having problems getting some Perl code to work (im a programming
newbie).

Have you considered any of the self-help solutions that the regulars
here _always_ tell _all_ newbies they should try before asking others
for help?

Do you realise that not doing so is saying in no uncertain terms that
you value the time of the people you are asking for help considerably
less than you value your own?

Please read the posting guidelines.
The aim of the code is to read certain text from a file,
print it to screen then allow the user to make a choice based on that
output. Well, that's the aim so far anyway (im about half way through
the code). Ive been stuck on this however. Im getting the error "Use
of uninitialized value in print at... line 26, <STDIN> line 1."
Ive spent most of the day trying to work out what's wrong,

You see, false lazyness doesn't pay - even in the relatively short term
let alone the medium or long term.
The code is,

Not declaring all variables in the smallest applicable lexical scope.
(Can you please explain how we could have been any more forceful about
the importance of doing this).

Not using strict (to detect when you've forgotten to declare a variable).

Not indented to make it readable.

Anyhow the following looks odd...
$prices2 = @raw_data;
@prices1to5 = split (/:/, $prices2);

Since $prices2 is the number of elements in the array @raw_data it will
be a number and it does not therefore make sense to split it on /:/.
I cant pick up the error despite going over it many times & trying a
number of things

Have you tried inserting diagnostic print()s to see if variables contain
what you expect? This is always a good idea.
 
A

axel

Jon Anderson said:
Im having problems getting some Perl code to work (im a programming
newbie). The aim of the code is to read certain text from a file,
print it to screen then allow the user to make a choice based on that
output. Well, that's the aim so far anyway (im about half way through
the code). Ive been stuck on this however. Im getting the error "Use
of uninitialized value in print at... line 26, <STDIN> line 1."

The warning indicates that you are trying to print out a value from a
variable which has not been initialised - i.e. no value has been
assigned to that variable.
Ive spent most of the day trying to work out what's wrong, but have
come up empty handed. The code is,
print "\n";
$prices2 = @raw_data;
@prices1to5 = split (/:/, $prices2);

You have assigned the length of @raw_data to $prices2.
It makes no sense to try to split this numb er.

The array @prices1to5 will contain one item $prices1to5[0] which is set
to whatever the length of @raw_data is.
print "Please enter the item to be purchased..\n\n";
chomp($selectitem = <STDIN>);
if($selectitem == 1)
{
print "\n";
print "You selected item 1, which sells for\n";
print $prices1to5[1];

Therefore as $prices1to5[1] has not been assigned a value, the warning
is generated.

May I suggest for general readability that you indent statements within
loops. See:

perldoc perlstyle

Axel
 
C

Chris Mattern

Jon said:
Hi,

Im having problems getting some Perl code to work (im a programming
newbie). The aim of the code is to read certain text from a file,
print it to screen then allow the user to make a choice based on that
output. Well, that's the aim so far anyway (im about half way through
the code). Ive been stuck on this however. Im getting the error "Use
of uninitialized value in print at... line 26, <STDIN> line 1."
Ive spent most of the day trying to work out what's wrong, but have
come up empty handed. The code is,

$lnum = 0;
open (INPUT, "file.txt") or die "Error, can't find file\n";
@raw_data=<INPUT>;
close(INPUT);
#Print to screen the pricelist in the text file
foreach $price (@raw_data)
{
@pricelist = split (/:/, $price);
print "$lnum" . " " . "$pricelist[1]\n" if @pricelist != 1;
$lnum ++;
}
print "\n";
$prices2 = @raw_data;
@prices1to5 = split (/:/, $prices2);
print "Please enter the item to be purchased..\n\n";
chomp($selectitem = <STDIN>);
if($selectitem == 1)
{
print "\n";
print "You selected item 1, which sells for\n";
print $prices1to5[1];
$item = 1;
}
elsif($selectitem == 2)
{
print "\n";
print "You selected item 2, which sells for\n";
print $prices1to5[2];
$item = 2;
}
elsif($selectitem == 3)
{
print "\n";
print "You selected item 3, which sells for\n";
print $prices1to5[3];
$item = 3;
}
elsif($selectitem == 4)
{
print "\n";
print "You selected item 4, which sells for\n";
print $prices1to5[4];
$item = 4;
}
elsif($selectitem == 5)
{
print "\n";
print "You selected item 5, which sells for\n";
print $prices1to5[5];
$item = 5;
}
else
{
print "\n";
print "Invalid item selection! No such item\n";
}


---

The code at line 26 is

18 $prices2 = @raw_data;
19 @prices1to5 = split (/:/, $prices2);
20 print "Please enter the item to be purchased..\n\n";
21 chomp($selectitem = <STDIN>);
22 if($selectitem == 1)
23 {
24 print "\n";
25 print "You selected item 1, which sells for\n";
26 print $prices1to5[1];

---

I cant pick up the error despite going over it many times & trying a
number of things after looking for answers online. Any help would be
greatly appreciated :)

Well, first of all, it seems like it would be so much simpler to say:

print "You selected item $selectitem, which sells for\n";
print $prices1to5[$selectitem];

rather than all those ifs...

Second of all, you're getting that warning (not error) because
$prices1to5[1] isn't defined, that simple. $prices2 contains
a single number; how many elements are in @raw_data. You then
split it on :. Since there are no :s in $prices2, the number
goes in @prices1to5[0] (you *are* aware that Perl arrays start
at 0, right?). Any other element comes up as undefined.
--
Christopher Mattern

"Which one you figure tracked us?"
"The ugly one, sir."
"...Could you be more specific?"
 
A

A. Sinan Unur

(e-mail address removed) (Jon Anderson) wrote in
Im having problems getting some Perl code to work (im a programming
newbie).

You should ask for all the help the perl can give you.

....
Im getting the error "Use of uninitialized value in print at...
line 26, <STDIN> line 1."

FYI, that is a warning, not an error.
Ive spent most of the day trying to work out what's wrong, but have
come up empty handed. The code is,

You should have

use strict;
use warnings;

and possibly

use diagnostics;
$lnum = 0;

my $lnum = 0;

Base on the name of the variable, I am assuming this has to do with
counting line numbers in the file. Perl has a builtin variable that does
this for you.
open (INPUT, "file.txt") or die "Error, can't find file\n";

Unless there is a specific reason to do otherwise, prefer the three
argument form of open using lexical filehandles:

open my $input, '<', 'file.txt'
or die "Error opening file.txt: $!";

open can fail even when the file can be found. Use $! to convey the
reason open failed.
@raw_data=<INPUT>;

No need to slurp the entire file.
close(INPUT);
#Print to screen the pricelist in the text file
foreach $price (@raw_data)

This is misleading. @rawdata contains lines from the file
@pricelist = split (/:/, $price);

which seem to contain entries such as

128 MB Flash Drive: $14.99
print "$lnum" . " " . "$pricelist[1]\n" if @pricelist != 1;
$lnum ++;
}
print "\n";
$prices2 = @raw_data;

As others have pointed out, assigning the number of lines in the
original file to $prices2
@prices1to5 = split (/:/, $prices2);

and splitting that causes the warning to be emitted.
print "Please enter the item to be purchased..\n\n";
chomp($selectitem = <STDIN>);
if($selectitem == 1)

Whenever you see tedious repetition like this, you should remember that
you are dealing with a computer program. The fact that the program needs
to repeat things does mean that the *programmer* needs to repeat them as
well.
I cant pick up the error despite going over it many times & trying a
number of things after looking for answers online.

Did your online reading include the posting guidelines for this group?
If yes, why did you choose not to follow them? If not, why not?
Any help would be greatly appreciated :)

Here is one way to read the first five description/price information
from a file, display the information as a menu, and get the user's
input. It would be most useful to you to study each of the features used
(consult the documentation that comes with Perl. To get an idea of what
information is available, you can use perldoc perltoc.

Warnings: The script below ignores various issues such as the cases
where there are fewer than expected entries, how to choose among more
than 9 items etc.

#! /usr/bin/perl

use strict;
use warnings;

use constant ITEMS_TO_SHOW => 5;

my @menu;

while(<DATA>) {
last if $. > ITEMS_TO_SHOW;
chomp;
last unless length $_;
my ($desc, $price) = split /:/;
push @menu, { desc => $desc, price => $price };
printf "[ %d ] : %s (%s)\n", $., $desc, $price;
}

$| = 1;
print "Select an item: ";
my $item = <STDIN>;
chomp($item);

unless($item >= 1 and $item <= ITEMS_TO_SHOW) {
die "Item number out of range\n";
}

print "You selected item $item whose price is: ",
$menu[$item - 1]->{price}, "\n";

__DATA__
128 MB Flash Drive : $14.99
Bahamas Vacation : $999.99
10/100/1000 NIC : $19.99
Pizza : $11
Soda : $1.50
Mazda Protege: $14999
Movie Ticket: $6.50
 
T

Tad McClellan

A. Sinan Unur said:
(e-mail address removed) (Jon Anderson) wrote in


FYI, that is a warning, not an error.


Said with a non-petty phrasing!

Golly, I'm feeling all warm and fuzzy here at the clpmisc lovefest.

<g>
 
A

A. Sinan Unur

Said with a non-petty phrasing!

Golly, I'm feeling all warm and fuzzy here at the clpmisc lovefest.

<g>

I wish I had seen your compliment before I went off on a rant in another
message. I might not have done it. I'll try to cancel that one.

Sigh!

Thanks, BTW.

Sinan.
 
A

axel

As others have pointed out, assigning the number of lines in the
original file to $prices2
and splitting that causes the warning to be emitted.

No, not that split and assignment, both of which are valid
Perl code and will raise no warning.

The warning comes afterwards from trying to use an element of
@proces1to5 which has not been assigned.

Just making a note in case the OP is confused.

Axel
 

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,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top