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

Hello Monks!! A tiny portion of more homework.
I am first off creating a file with the particular contents seen below. Once created I want to close it and then reopen it. Upon opening the second time I want to read each line and make the key the first and last name and the value the password.
I'm unclear where I am going wrong.
Thank you all as always!
#!/usr/bin/perl use strict; use warnings; open (FH, ">students.txt"); print FH "Perry*Steve*234\nSmith*Jane*456\nJones*Mary*567\n"; close (FH); $students="students.txt"; open(FH, $students) or die("Could not open file!"); while(<FH>) { @students = split (/*/, $_); $key = $students[0],$students[1]; $hash{$key} = $students[2]; }

Replies are listed 'Best First'.
Re: Open a file and put the contents in a hash with a value
by cosmicperl (Chaplain) on Apr 11, 2008 at 21:54 UTC
    Hi,
      If you are using strict you'll need to my that $students variable. Such as:-
    my $students="students.txt";
    Same goes for @student, $key and your hash. Also * is special in terms of a regexp, so you'll want a \ in front.

    Here is how I'd do it:-
    #!/usr/bin/perl use strict; use warnings; open(FH, ">students.txt"); print FH "Perry*Steve*234\nSmith*Jane*456\nJones*Mary*567\n"; close(FH); my %hash; my $students = "students.txt"; open(FH, $students) or die("Could not open file!"); while (<FH>) { my ($firstname, $lastname, $password) = split (/\*/, $_); $hash{"$firstname $lastname"} = $password; }#while
    You can use parenthasis when defining a has key so no need to create the extra $key variable.
    Actually, do you have a strong reason for using * rather than the pipe symbol |? Would probably be better with the pipe symbol. How about:-
    #!/usr/bin/perl use strict; use warnings; open(FH, ">students.txt"); print FH "Perry|Steve|234\nSmith|Jane|456\nJones|Mary|567\n"; close(FH); my %hash; my $students = "students.txt"; open(FH, $students) or die("Could not open file!"); while (<FH>) { my ($firstname, $lastname, $password) = split (/\|/, $_); $hash{"$firstname $lastname"} = $password; }#while
    Aghhh... I love newbie questions, makes me feel like I know stuff ;)

    Lyle
      I guess more so of what I am trying to do is give the first name and last name one variable such as $name and its value being the password.
      Mainly so later in the script I can have them input their first name then last name, join them and then match them against the $name and give them the password if the $name is found.

        That's generally not such a great idea, even if you avoid the badness of having spaces in hash keys. Smashing strings together loses information that you may need later - e.g., you won't know if user "johara" used to be "jo hara" or "j ohara" (contrived, but you see the point.) Once you learn about references, you might want to consider a list of hashes (LoH) or a hash of hashes (HoH) to keep track of this kind of thing - e.g., "$user[0]->{Perry}{Steve} = 234" or "$user{0}{Perry}{Steve} = 234". That way, even if you get another "Perry, Steve", his unique number will keep him distinct from the previous one.

        ...but I'm wandering far afield. :) If you've just absolutely gotta do it the way you're describing, then at least separate the chunks with a delimiter that's not likely to occur in them - e.g., an underscore. My version of your script follows, with suggested modifications.

        #!/usr/bin/perl use strict; use warnings; # Might as well declare this early on and save some typing :) my $s = "students.txt"; # *Always* check system operations for errors open Fh, ">", $s or die "$s: $!\n"; print Fh "Perry*Steve*234\nSmith*Jane*456\nJones*Mary*567\n"; close Fh; my (@bits, %pass); # Don't guess at the error ahead of time - get the real story with '$! +' open Fh, "<", $s or die "$s: $!\n"; while(<Fh>) { @bits = split /\*/; $pass{join "_", @bits[0,1]} = $bits[2]; } # Let's see what we got in the hash printf "%s:\t%d\n", $_, $pass{$_} for sort keys %pass;
        
        
        -- 
        Human history becomes more and more a race between education and catastrophe. -- HG Wells
        
      By the way, thank you for the quick response!!!