Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

[SOLVED] Does split not work with a pipe?

by jaffinito34 (Acolyte)
on Nov 09, 2012 at 17:07 UTC ( #1003183=perlquestion: print w/ replies, xml ) Need Help??
jaffinito34 has asked for the wisdom of the Perl Monks concerning the following question:

My script checks the username and password entered to that of a passwd file. If anything is incorrect the program dies. If they match, another file gets opened so that the user can see their info in the file. However, the file is split up by pipes (|) so when I use a while loop to split the file, the variables do not get properly assigned. Here's the code, the problem is the while loop at the bottom:

#! /usr/bin/perl # CSC 310 Project # 3 #opening passwd file open (PSWD, '<', 'passwd.txt'); #getting username and password #converting username to lowercase if anything is entered in CAPS print "Please enter your username: "; chomp($userN = <STDIN>); $username = lc($userN); print "Please enter your password: "; #hiding password system ("stty -echo"); chomp($passwd = <STDIN>); print "\n$passwd\n"; $matchCount = 0; #reading passwd.txt and assigning values while ($lines = <PSWD>){ ($user,$pswd,$userID,$groupID,$info,$home,$shell) = split ':', $li +nes; #checking username entered vs that in the passwd file if ($username eq $user){ print "Checking username... MATCH\n"; #keeps track if username matches or not $matchCount += 1; #checking password entered vs that in the passwd file if ($passwd eq $pswd){ print "Checking password... MATCH\n"; } else{ print "Password does not match!\n"; } last; } } # if matchcount did not change, username did not match killing the pro +gram if ($matchCount == 0){ die ("\"$username\" does not match any users in our database!\n"); } #opens accounting data file open (DATA, '<', ''); #reading accounting data and assigning values while ($line = <DATA>){ ($lastName,$firstName,$ssn,$address,$city,$state,$zip,$payDate,$ho +urs,$rate,$taxes,$deductions,$notes) = split '|', $line; print "$lastName\n"; }

When I print $lastName, it only returns the first letter of the last name rather than the whole thing. If I was to print $lastname . $firstname, it would print the first 2 letters of the last name. Any ideas what is going on here?

Comment on [SOLVED] Does split not work with a pipe?
Download Code
Re: Does split not work with a pipe?
by Corion (Pope) on Nov 09, 2012 at 17:10 UTC

    See split. split takes a regular expression, not a string.

      Thanks, just had to exit the pipe

Re: Does split not work with a pipe?
by jethro (Monsignor) on Nov 09, 2012 at 17:16 UTC

    The first parameter of split is a regex pattern, not a string. Now the regex, lets spell it m/|/, matches the empty string. If you read the perldoc of split, you will find the following sentence:

    A pattern matching the empty string (not to be confused with an empty pattern "//", which is just one member of the set of patterns matching the epmty string), splits EXPR into individual characters.

    PS: Please use strict; use warnings;.

Re: [SOLVED] Does split not work with a pipe?
by runrig (Abbot) on Nov 09, 2012 at 17:29 UTC
    Here's the code, the problem is the while loop at the bottom

    If you're having trouble with split, you should only have to post at most 3 or 4 lines of code to demonstrate the problem. As it is, I had trouble even finding where you were even calling the function, though I guessed what the problem was from the title.

Re: [SOLVED] Does split not work with a pipe?
by Tanktalus (Canon) on Nov 10, 2012 at 14:37 UTC

    First comment. Don't use DATA as your filehandle. That filehandle already exists and is used for something different.

    Second, use lexical filehandles instead of globals. open my $data, '<', ''

    Third, check that the open succeeded. Especially when you're dealing with a filename that isn't an absolute path, the current working directory (cwd) could change simply because the user called your script from the wrong directory. open my $data, '<', '' or die "Can't read $!"

    Fourth, use Text::CSV_XS to read delimited data rather than splitting. It handles edge cases for you. It also handles the first three comments, too ;-)

    Fifth, use DBD::CSV to handle data stores like this. IMO, treating tables of data as, well, tables of data, generally works better. It also uses Text::CSV_XS under the covers.

    Ok, now on to some meta-comments (comments on the comments). I see this is homework. Thank you for not hiding that fact ;-) . Your professor may not like comments 4 and 5 above. But the first three are still valid, even for homework. The only reason 4 and 5 might be disliked by your professor is that the goal of the excersise is not to actually accomplish anything, but to learn stuff. (Which was always one of the things I disliked about school - I prefer to learn stuff through accomplishing things.) And Text::CSV_XS will bypass learning split, and DBD::CSV will bypass learning Text::CSV_XS.

    Oh, a sixth coment, I just noticed: Perl has many quoting operators so that you can avoid (or at least minimise) LTS (leaning toothpick syndrome). So, instead of die ("\"$username\" does not match any users in our database!\n");, I'd suggest using the qq operator and ending up with: die (qq["$username" does not match any users in our database!\n]);. See how I've removed two backslashes (leaning toothpicks)? Note that you can do die (qq'"$username" does not match any users in our database!\n'); as well, but don't - the use of single quotes as a double-quote delimiter will get you strangled :-)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1003183]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (12)
As of 2014-10-01 17:31 GMT
Find Nodes?
    Voting Booth?

    What is your favourite meta-syntactic variable name?

    Results (31 votes), past polls