psychoto has asked for the wisdom of the Perl Monks concerning the following question:

I'm very new to perl, so go easy on me. I'm creating an author search program which prompts user for input. Then opens an input file, splits all the info into vars, and displays output generated based upon search.

Input file is similar to this:
Taliesin:Lawhead:Celtic Novel:8.99
History of the 20th Century:Sage:History:27.99
The Twilight of Courage:Thoene:Historical Novel:15.99

This is what I have so far:
print "Author to search for:"; chomp($search = <STDIN>); open (INPUT, "books.txt"); while (<INPUT>){ chomp $_; ($title, $author, $genre, $price) = split /:/,$_; if ($search == $author) { $totalprice += $price; @info = ($title, $genre, $price); $found++; } } print "$found books by $author were found...\n"; print "They are:\n"; print "\tBook Title\t\t\tGenre\tPrice"; print @info; print "\tTotal price of these books by $seach is $totalprice"; close INPUT;
HELP????

Replies are listed 'Best First'.
Re: Searching input file
by rbc (Curate) on Feb 27, 2002 at 23:29 UTC
    Hi psychoto!
    The Monks are big on -w and use strict;
    and rightfully so. So if your not doing that
    you might want to start.

    In your script you probably want to change the line ...
    if ($search == $author) {
    ... to ...
    if ($search eq $author) {

    because $search and $author do not contain "numbers".
    There are other stylistic things I am sure other monks
    will comment on.
Re: Searching input file
by jlongino (Parson) on Feb 28, 2002 at 04:15 UTC
    If you had used strict, an error message would have pointed out that you typo'd $seach and probably meant $search in your last print statement.

    Also, you might want to consider a different delimiter character than ":". The colon appears in many book titles, so what will happen when you eventually encounter one?

    Here is another way to do it:

    use strict; my (@info, $found); my $totalprice = 0; print "\n\nAuthor to search for: "; chomp (my $search = <STDIN>); print "\n\n"; while (<DATA>){ chomp $_; my ($title, $author, $genre, $price) = split ":"; if (lc $search eq lc $author) { $totalprice += $price; push @info, $_; $found++; } } if ($found) { print "\n\nNumber of matching books by $search: ", $found, "\n\n"; print pack('A40 A20 A7','Title','Genre', 'Price'),"\n"; print '-' x 39, ' ', '-' x 19, ' ', '-' x 7, "\n"; foreach (@info) { my ($title, $author, $genre, $price) = split ":"; print pack("A40 A20 A7", $title, $genre, $price), "\n"; } print "\n\tTotal price of matching book(s): $totalprice\n"; } else { print "\nNo matching books for author: $search\n\n"; } __DATA__ Taliesin:Lawhead:Celtic Novel: 8.99 History of the 20th Century:Sage:History:27.99 The Twilight of Courage:Thoene:Historical Novel:15.99 Historical Perspectives:Lawhead:History:35.00

    Results:
    Author to search for: lawhead Number of matching books by lawhead: 2 Title Genre Price --------------------------------------- ------------------- ------- Taliesin Celtic Novel 8.99 Historical Perspectives History 35.00 Total price of matching book(s): 43.99

    --Jim

      Thanks a lot everyone! The info you all gave will help a ton! Sorry bout the whole -w/use strict thing....first post here. I'm very new to the Perl syntax but I'm starting to get a better grasp everyday.

      --psychoto

      It is the Mind,
      That is the Mind,
      Confusing the Mind.
      Do not Mind, Oh mind,
      to the Mind.

      ---Miyamoto Musashi
Re: Searching input file
by tfrayner (Curate) on Feb 28, 2002 at 00:43 UTC
    Hi,

    Without actually running your script I would suggest that it will only return the last item found, and the total number and price of all items found. This is because each iteration of your while loop wipes out the previous entry. The simplest way to get around this would be to print out your info on each iteration rather than at the very end. Alternatively, you might want to use a hash (or array) of arrays (see perlman:perlref for a discussion of references, should you need it).

    Other than that, I second the suggestion to use strict and warnings :-)

    HTH, Tim

Re: Searching input file
by strat (Canon) on Feb 28, 2002 at 00:35 UTC
    Changement: there were some typos I'll correct by now. I really should have run it before, sorry

    Maybe this works, although somehow you didn't tell what your problem is...

    #!perl -w use strict; print "Author to search for:"; my $search = <STDIN>; chomp($search); my $totalprice = 0; my $found = 0; my @info = (); my ($title, $autor, $genre, $price); open (INPUT, "books.txt") or die "Error: $!"; # always check for error +s while (<INPUT>){ chomp $_; ($title, $autor, $genre, $price) = split (/:/,$_); if ($search eq $autor) { # eq for stringcompare, == for numerical $totalprice += $price; push (@info, [ $title, $genre, $price]); $found++; } } print "$found books by $autor were found...\n"; print "They are:\n"; print "\tBook Title\t\t\tGenre\tPrice"; foreach my $info (@info){ print join("\t", @$info), "\n"; } print "\tTotal price of these books by $search is $totalprice"; close INPUT;

    Best regards,
    perl -le "s==*F=e=>y~\*martinF~stronat~=>s~[^\w]~~g=>chop,print"

      A few of things. You have a typo ($totalpriece) which leaves $totalprice undefined, $author is not scoped outside the while, and $seach is a typo.

      I didn't actually look to see if the code worked. It's sort of pointless to add use strict and -w if you don't try to run it. The disclaimer "This code was not tested" would have been better than Maybe this works . . . .

      --Jim

Re: Searching input file
by Anonymous Monk on Feb 28, 2002 at 09:27 UTC
    What is your question / problem? open looks suspect: open (INPUT, "<books.txt"); are you missing '<' or '>' read, write, or append the file you are opening?
      Hi

      I just looked this one up in man perlopentut:
       
      A few things to notice.  First, the leading less-than is
      optional.  If omitted, Perl assumes that you want to open
      the file for reading.