我正在做一项任务,如果用户成功登录,我必须让他们登录(对照文件检查他们的用户名/密码),然后我需要打印他们的工资数据,这些数据存储在另一个名为in-accounting.data的文件中在会计文件中,我可以使用一些帮助来了解如何只打印登录用户的数据,有什么建议吗?这些文件和代码中的所有ssn、电话号码、地址和人员都是假的,它们只是为完成任务而提供的数据
11-6-12更新以反映建议的更改,现在它以我最初希望的方式运行到
#!/usr/bin/perl
use warnings;
use strict;
use Digest::MD5 'md5_hex';
open (PSWD, '<', 'password.passwd');
#getting username and password
#converting username to lowercase if username is entered in CAPS
print "Please enter your username: ";
chomp(my $userN = <STDIN>);
my $username = lc($userN);
############################################
print "Please enter your password: ";
chomp(my $password = <STDIN>);
my $passwd=md5_hex($password);
###############################################
my $matchCount = 0;#used later to make sure username and password match file
#reading password.passwd and assigning values
while (my $lines = <PSWD>){
my($user,$pswd,$userID,$groupID,$info,$home,$shell) = split ':', $lines;
#checking username entered vs that in the passwd file
if ($username eq $user){
print "Checking username... MATCHn";
$username=$info;
#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... MATCHn";
my ($first,$last)=split(" ", $info);
accounting($first,$last);
}
else{
print "Password does not match!n";
}
last;
}
}
# if matchcount did not change, username did not match killing the program
if ($matchCount == 0){
die (""$username" does not match any users in our database!n");
}
sub accounting{
my $first_name=shift;
my $last_name=shift;
open(my $fh, '<', 'IN-accounting.data') or die "cannot open accounting file $!";
while (my $lines = <$fh>){
chomp $lines;
my @fields = split(/|/, $lines);
push @data2, @fields;
my($Lname,$Fname,$ssn,$address)=($fields[0],$fields[1],$fields[2],$fields[3]);
my($city,$state,$zip,$payDate)=($fields[4],$fields[5],$fields[6],$fields[7]);
my($hours,$rate,$taxes,$deductions,$notes)= ($fields[8],$fields[9],$fields[10],$fields[11],$fields[12]);
next if $Lname ne $last_name and $Fname ne $first_name;
my ($Gpay)= eval($hours)*eval($rate);#gross pay
my ($Tpay)=$Gpay-($taxes+$deductions);#total pay
my $Essn=substr($ssn,+-4);#edited ssn
print "$Fname $Lnamen";
print "$addressn";
print "$city $state $zipn";
print "SSN: xxx-xx-$Essnn";
print"n";
print "Pay Date: $payDate";
print"n";
print"You had $hours hours at $$rate/hourn";
print"Gross Pay: $Gpayn";
print"Taxes:$-$taxesn";
print"Deductions:$-$deductionsn";
print"Total Pay: $Tpayn";
print"n";
print"Notes:$notesnn";
}
print"press enter to quit: ";
my $quit=<>;
if ($quit){ exit;}
}
密码.密码
amon9640:4cb9c8a8048fd02294477fcb1a41191a:502:25:亚历山大星期一:/home/payroll:/bin/payrolliart1373:4cb9c8a8048fd02294477fcb1a41191a:501:25:Inigo Arterbury:/home/payroll:/bin/payrollwher0210:4cb9c8a8048fd02294477fcb1a41191a:502:25:Wardell Herman:/home/payroll:/bin/payroll
会计档案
星期一|Alexander|815-19-9640|4662 Dewy Subdivision |Owltown|Oregon|97434-8480|1998|18|19|21.68|60.28|2.24| Payroll正在审计账目,报告很快就会到期。
Arterbury|Inigo |037-30-1373|987 Rocky Island Byway|Christmas City|New Mexico |88023-3889|4/1/1993|9|7.02|17.75|12.71|审计完成。发现违规行为。
Herman | Wardell | 114-29-0210 | 5555 Cinder Forest Wynd | White Eyes Town | Washington | 98707-5628 | 2003年10月| 37 | 3.07 | 41.90 | 20.89 |审计完成。发现违规行为。
我将跳过安全问题。让我们来看看一些事情:
您的accounting
子程序应该做什么?是否为用户打印工资单?您没有向子例程传递任何数据。子程序如何知道要打印哪个用户的工资单?
为什么不做这样的事?
accounting($Fname, $Lname);
sub accounting {
my $first_name = shift;
my $last_name = shift;
if (not $first_name or not $last_name) {
die "You need a first name and a last name...)
}
现在,您可以逐行循环查看会计文件,查找$first_name
和$last_name
匹配的行。
while (my $lines = <$fh>){
chomp $lines;
my ( $Lname, $Fname, $ssn, $address,
$city, $state, $zip, $payDatek,
$hours, $rate, $taxes,$deductions, $notes) = split /|/, $lines;
#Skip over non matching lines
next if $Lname ne $last_name and $Fname ne $first_name;
你的代码中有一些虚假错误。我注意到了一些快速的:
push @data2, @fields;
您正在将数组的引用推送到数组中my ( $Lname, $Fname, ... $notes) = %fields;
字段是一个数组,而不是散列
我很惊讶你的程序编译时出现了这些问题。
并且,请在代码中使用空格。它使阅读和理解更加容易。
哇,您的方法存在一些严重的安全问题。我试着在评论中指出一些。
要专注于您的特定问题,您需要某种方法将用户链接到会计数据,然后按用户进行筛选。理想情况下,您应该将原始数据摄取到具有关系约束的数据库中,以使这更容易。但对于目前的方法,你可以做一些类似的事情:
next unless "$Fname $Lname" eq $username;
将其放在变量名到返回的正则表达式字段的映射之后。