我是Perl的新手,我的代码可能无法解决问题。我相信我正确地使用了语法,但我怀疑问题可能在于这一行:
push @students, \%information;
我想要的是学生列表中包含学生信息的哈希值。我期望的是,在每次添加学生之后,创建学生信息的另一个哈希并且链接到列表的最新索引。但是,如果我同时输入学生数据,则最新会覆盖之前的数据,因此当您打印它时,您将在上一个列表条目中看到最新输入信息的副本。如果我输入1名学生并在添加后立即查看,则输入另一名学生,最新学生将覆盖以前的学生。有人可以解释一下吗?谢谢!
这是我的代码:
use strict;
use warnings;
my $userchoice = 0;
my $i;
my @students = (); #empty array
my %information = ();
while ( $userchoice != 4 ) {
print "------------------------------\n";
print "Welcome! What would you like to do?\n";
print "[0]Create Student Record\n";
print "[1]Edit Student Record\n";
print "[2]View Student Record\n";
print "[3]Delete Student Record\n";
print "[4]Exit\n";
print "Your Choice : ";
$userchoice = <STDIN>;
chomp($userchoice);
if ( $userchoice == 0 ) {
print "-----------\n";
print "CREATE STUDENT RECORD.\n";
if ( $#students <= 9 ) {
print "Name : ";
$information{"name"} = <STDIN>;
chomp( $information{"name"} );
push @students, \%information;
}
print "Student Record Full. " if ( $#students >= 10 );
}
if ( $userchoice == 2 ) {
print "\nVIEW STUDENTS.\n";
print "[0]View One Student\n";
print "[1]View All Students\n";
print "[2]Back to Main Menu\n";
print "Your Choice : ";
$userchoice = <STDIN>;
if ( $userchoice == 1 ) {
print "VIEW ALL STUDENTS.\n";
print "STUDENT 1---------------\n";
print "Name : ", $students[0]->{"name"}, " \n";
print "STUDENT 2---------------\n";
print "Name : ", $students[1]->{"name"}, " \n";
}
}
}
答案 0 :(得分:4)
这总是将对同一哈希的引用推送到数组push @students,\%information;
举例说明:
my %hash = ( index => 0 );
my @list = ();
foreach my $i (1..3) {
$hash{index} = $i;
push @list, \%hash;
}
for ( my $i=0; $i<@list; $i++ ) {
print "item $i - $list[$i] - $list[$i]->{index}\n";
}
从输出中注意每个地址的地址相同:
item 0 - HASH(0x4c8068) - 3
item 1 - HASH(0x4c8068) - 3
item 2 - HASH(0x4c8068) - 3
您可以通过在循环中声明%信息来修复
while($userchoice!=4){
my %information = ();
或者在推送时强制使用新参考:
push @students, { %information };
答案 1 :(得分:2)
您的问题出现是因为您为每个学生提供了数组中相同哈希的引用:
push @students, \%information;
对此的一个解决方案是简单地为每条记录创建一个新的匿名哈希:
push @students, { %information };
但是,我相信您也可以使用课程来限制变量的范围。
在声明变量时始终使用尽可能小的范围。这既有助于记录您的代码,也可以减少意外滥用此类变量的可能性。
以下是重写脚本以删除全局范围中使用的所有变量:
use strict;
use warnings;
my @students = (); #empty array
while (1) {
print "------------------------------\n";
print "Welcome! What would you like to do?\n";
print "[0]Create Student Record\n";
print "[1]Edit Student Record\n";
print "[2]View Student Record\n";
print "[3]Delete Student Record\n";
print "[4]Exit\n";
print "Your Choice : ";
chomp( my $userchoice = <STDIN> );
last if $userchoice == 4;
if ( $userchoice == 0 ) {
print "-----------\n";
print "CREATE STUDENT RECORD.\n";
if ( @students <= 10 ) {
print "Name : ";
chomp( my $name = <STDIN> );
push @students, { name => $name };
}
print "Student Record Full. " if ( @students > 10 );
}
if ( $userchoice == 2 ) {
print "\nVIEW STUDENTS.\n";
print "[0]View One Student\n";
print "[1]View All Students\n";
print "[2]Back to Main Menu\n";
print "Your Choice : ";
chomp( my $userchoice = <STDIN> );
if ( $userchoice == 1 ) {
print "VIEW ALL STUDENTS.\n";
for my $i ( 1 .. @students ) {
print "STUDENT $i---------------\n";
print "Name : ", $students[ $i - 1 ]{"name"}, " \n";
}
}
}
}
答案 2 :(得分:1)
如评论中所述:
每次都需要使用对新哈希的引用,而不是每次都尝试引用相同的哈希。最简单的方法是在循环体内定义
%information
。
您的代码目前是:
my %information = ();
while ( $userchoice != 4 ) {
print "------------------------------\n";
如果使用:
,它将正常工作(或者至少,它的这方面可以正常工作)while ( $userchoice != 4 ) {
my %information = ();
print "------------------------------\n";