#BY Weigun blog:http://blog.chinaunix.net/u2/70443/
use strict;
use Data::Dumper;
$|=1;
my $stu={}; #哈希表,存放学生信息
while(1) #主循环
{
my $choose=&main;
redo if $choose!~/^\d$/;
$stu=&add($stu) if $choose ==1;
$stu=&modify($stu) if $choose ==2;
$stu=&delete($stu) if $choose ==3;
&search($stu) if $choose ==4;
&statistics($stu) if $choose==5;
&grade_sort($stu) if $choose==6;
exit if $choose==7;
print Dumper $stu;
}#主循环结束
sub main
{
system("cls");
print <<eof;
学生成绩管理系统
1.录入学生成绩信息
2.修改学生成绩信息
3.删除学生成绩信息
4.查询学生成绩信息
5.成绩统计
6.成绩排名
7.退出
eof
print '请选择:';
chomp(my $choose=<STDIN>);
return $choose;
}
sub add
{
my $stu=shift;
my ($id,$name,$sex,$age,@grades);
my $counter=1;
system("cls");
print "\t\t\t录入学生成绩信息\n";
while(1)
{
print "新增第$counter个学生\n";
$id=&get_id($stu,1);#最后区别增加和修改
$name=&get_name($stu,$id);#无返回值
$sex=&get_sex($stu,$id);#无返回值
$age=&get_age($stu,$id);#无返回值
@grades=&get_grade($stu,$id);#无返回值
++$counter; #学生计数器
#判断是否继续
return $stu unless &is_continue;
}#while
return $stu;
}
sub get_id #1:add new 0 for search
{
my $id;
my $stu=shift;
my $is_add_new=shift;
{ #id
print '请输入学生学号:';
chomp($id=<STDIN>);
# unless ($id=~/\d{10}/)
# {
# print "请输入正确的学号\n";
# redo;
# }
redo unless &check_id($id);
#print '$id=',$id,"\n";
if($is_add_new and exists $stu->{$id})
{
print "该学号的学生已存在.\n";
redo;
}
$stu->{$id}={} if $is_add_new;
}#id
return $id;
}
sub get_name
{
my $name;
my ($stu,$id)=@_;
{ #name
print '请输入姓名:';
chomp($name=<STDIN>);
if($name!~/^.{1,10}$/)
{
print "请输入少于10个字符的名字.\n";
redo;
}
}#name
$stu->{$id}->{name}=$name;
return $name;
}
sub get_sex
{
my $sex;
my ($stu,$id)=@_;
{ #sex
print '请输入性别:';
chomp($sex=<STDIN>);
if($sex=~/^[fFMm]$/)
{
$sex=~/^[Ff]$/?($sex='女'):($sex='男');
}
else
{
print "请输入正确的性别(F/M)。\n";
redo;
}
#print $sex,"\n";
$stu->{$id}->{sex}=$sex;
}#sex
return $sex;
}
sub get_age
{
my $age;
my ($stu,$id)=@_;
{ #age
print '请输入年龄:';
chomp($age=<STDIN>);
unless ($age=~/^\d{1,2}$/ and $age!=0)
{
print "请输入正确的年龄(1-99)\n";
redo;
}
}#age
$stu->{$id}->{age}=$age;
return $age;
}
sub is_continue
{
{ #继续?
print "是否要继续增加(Y/N):";
chomp(my $flag=<STDIN>);
$flag=~/^[Yy]$/?(return 1):($flag=~/^[Nn]$/?(return 0):redo);
}
#######################
}
sub get_grade
{
#my ($sjk,$xmgl,$sjjg);
my ($stu,$id)=@_;
my $hash={sjk => '数据库',
xmgl => '项目管理',
sjjg => '数据结构'
};
my $total;
while(my ($key,$valuse)=each %$hash)
{
print $valuse,'成绩:';
chomp(my $grade=<STDIN>);
redo unless &is_grade_right($grade);
$stu->{$id}->{$key}=$grade;
$total+=$grade;
}
$stu->{$id}->{average}=sprintf("%.1f",$total/3);
#return ($sjk,$xmgl,$sjjg);
}
sub is_grade_right
{
my $grade=shift;
unless($grade=~/^\b(?:100|[1-9]?\d)\b$/)
#简单正则:/\b(?:100|[1-9]?\d)\b/
#花哨:/\b1??(?(?<=1)0|[1-9])?(?(?<=10)0|\d)\b/
{
print "成绩范围为0-100.\n";
return 0;
}
else
{
return 1;
}
}
sub modify
{
my $stu=shift;
my $choose=&modify_main;
&modify_by_id($stu) if $choose==1;
&modify_by_name($stu) if $choose==2;
return $stu if $choose==3;
return $stu;
}
sub modify_main
{
my $choose;
while(1)
{
system("cls");
print <<eof;
修改学生信息
1.按学号修改
2.按姓名修改
3.返回主菜单
eof
print '请选择:';
chomp($choose=<STDIN>);
redo if $choose!~/^[1-3]$/;
last;
}
return $choose;
}
sub modify_by_id
{
my $stu=shift;
my $id;
while(1)
{#check id
system("cls");
print "\t\t\t修改学生信息\n";
print "请输入学号:";
chomp($id=<STDIN>);
return $stu if $id==0;
redo unless &check_id($id) and &is_exist_id($stu,$id);
&show_stu_info($stu,$id);
&get_name($stu,$id);#无返回值
&get_sex($stu,$id);#无返回值
&get_age($stu,$id);#无返回值
&get_grade($stu,$id);#无返回值
print "信息已修改成功,1秒后返回.\n";
sleep 1;
last;
}
}
sub modify_by_name
{
}
sub delete
{
my $stu=shift;
my $id;
system("cls");
print "\t\t\t删除学生信息\n";
while(1)
{
print "请输入要删除的学号:";
chomp($id=<STDIN>);
return $stu if $id eq '0';
redo unless &check_id($id) and &is_exist_id($stu,$id);
last;
}
&show_stu_info($stu,$id);
while(1)
{
print "确定要删除吗?(Y/N)";
chomp(my $flag=<STDIN>);
#$flag=~/^[Yy]$/?(return 1):($flag=~/^[Nn]$/?(return 0):redo);
if($flag=~/^[Yy]$/)
{
delete $stu->{$id};
last;
}
elsif($flag=~/^[Nn]$/)
{
return $stu;
}
else
{
redo;
}
}
print "信息已删除,1秒后返回.\n";
sleep 1;
return $stu;
}
sub search
{
my $stu=shift;
system("cls");
my $choose=&search_main;
&search_by_id($stu) if $choose==1;
&search_by_name($stu) if $choose==2;
return if $choose==3;
}
sub search_main
{
print "t\t\t\查询学生信息\n";
while(1)
{
print "1.按学号查询\n";
print "2.按姓名查询\n";
print "3.返回主菜单\n";
print "请选择:";
chomp(my $choose=<STDIN>);
redo if $choose!~/^[1-3]$/;
return $choose;
}
}
sub search_by_id
{
my $stu=shift;
my $id;
while(1)
{
print "请输入要查询的学号:";
chomp($id=<STDIN>);
return 0 if $id eq '0';
redo unless &check_id($id) and &is_exist_id($stu,$id);
last;
}
&show_stu_info($stu,$id);
print "按回车键返回主菜单\n";
<STDIN>;
return $id;
}
sub search_by_name
{
my $stu=shift;
my $name;
{
print "请输入要查询的名字:";
chomp($name=<STDIN>);
if($name!~/^.{1,10}$/)
{
print "请输入少于10个字符的名字.\n";
redo;
}
}
my $flag=0;
for my $id(keys %$stu)
{
if($name eq $stu->{$id}->{name})
{
&show_stu_info($stu,$id);
#print "id=$id\n";
$flag=1;
}
}
print "找不到姓名为$name的学生\n" unless $flag;
print "按回车键返回主菜单\n";
<STDIN>;
return $name;
}
sub statistics
{
my $stu=shift;
my $flag=0;
print "\t\t\t不合格统计\n";
print '共有学生',&get_stu_number($stu),"人\n";
print '男生有',&get_man_number($stu),"人,女生有",&get_girl_number($stu),"人\n";
print "平均分不合格的学生如下:\n";
for my $id(sort keys %$stu)
{
&show_stu_info($stu,$id) if $stu->{$id}->{average} < 60;
$flag=1;
}
print "没有不合格的学生\n" unless $flag;
print "按回车键返回主菜单\n";
<STDIN>;
}
sub get_stu_number
{
my $stu=shift;
return scalar(keys %$stu);
}
sub get_man_number
{
my $stu=shift;
my $counter=0;
for my $id(keys %$stu)
{
++$counter if $stu->{$id}->{sex} eq '男';
}
return $counter;
}
sub get_girl_number
{
my $stu=shift;
my $counter=0;
for my $id(keys %$stu)
{
++$counter if $stu->{$id}->{sex} eq '女';
}
return $counter;
}
sub grade_sort
{
my $stu=shift;
system "cls";
print "\t\t\t成绩排序\n";
print "平均分由高到低排列如下:\n";
my @sorted_id=sort {$stu->{$b}->{average} <=> $stu->{$a}->{average} or $a cmp $b} keys %$stu;
&show_stu_info($stu,$_) foreach @sorted_id;
print "按回车键返回主菜单\n";
<STDIN>;
}
##############################################
###########公用函数############
sub check_id
{
my $id=shift;
#print "id=$id\n";
return 1 if $id eq '0';
# unless ($id=~/^\d{10}$/)
# {
# print "请输入正确的学号\n";
# return 0;
# }
return 1;
}
sub show_stu_info
{
my ($stu,$id)=@_;
print "学号为$id的学生信息如下:\n";
print <<INFO;
#####################################################################
学号:$id 姓名:$stu->{$id}->{name} 性别:$stu->{$id}->{sex} 年龄:$stu->{$id}->{age}
数据库:$stu->{$id}->{sjk}
项目管理:$stu->{$id}->{xmgl}
数据结构:$stu->{$id}->{sjjg}
总平均分:$stu->{$id}->{average}
#####################################################################
INFO
}
sub is_exist_id
{
my ($stu,$id)=@_;
unless(exists $stu->{$id})
{
print "该学号不存在.\n";
return 0;
}
return 1;
}
|