Newbie. Use of uninitialized value in print??

Discussion in 'Perl Misc' started by Jon Anderson, Apr 3, 2005.

  1. Jon Anderson

    Jon Anderson Guest

    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 :)
    Jon Anderson, Apr 3, 2005
    #1
    1. Advertising

  2. Jon Anderson wrote:

    > 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.
    Brian McCauley, Apr 3, 2005
    #2
    1. Advertising

  3. Jon Anderson

    Guest

    Jon Anderson <> wrote:
    > 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
    , Apr 3, 2005
    #3
  4. Jon Anderson wrote:

    > 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?"
    Chris Mattern, Apr 3, 2005
    #4
  5. (Jon Anderson) wrote in
    news::

    > 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




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

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Apr 3, 2005
    #5
  6. A. Sinan Unur <> wrote:
    > (Jon Anderson) wrote in
    > news::


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

    >
    > 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>


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Apr 3, 2005
    #6
  7. Tad McClellan <> wrote in
    news::

    > A. Sinan Unur <> wrote:
    >> (Jon Anderson) wrote in
    >> news::

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

    >>
    >> 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>


    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. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Apr 3, 2005
    #7
  8. Jon Anderson

    Guest

    A. Sinan Unur <> wrote:
    >> $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.


    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
    , Apr 3, 2005
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. G Kannan
    Replies:
    1
    Views:
    1,229
    Eric J. Roode
    Oct 11, 2003
  2. Sukhbir Dhillon
    Replies:
    1
    Views:
    6,247
    Joe Smith
    Apr 5, 2004
  3. Jesse Cary
    Replies:
    2
    Views:
    217
    J├╝rgen Exner
    Oct 15, 2004
  4. Pam
    Replies:
    2
    Views:
    284
    Brian McCauley
    Sep 19, 2006
  5. Replies:
    4
    Views:
    156
    Tad McClellan
    Nov 2, 2006
Loading...

Share This Page