我一直在尝试编写一个Perl脚本来获取用户输入名称并将它们存储在哈希值中。
我使用了以下代码,但显示错误。
这是我想回答的问题
在一行中将用户名称设为
first_name<space >last_name
接受这样的多个用户数据,直到输入退出为止 通过将姓氏作为键,将名字作为值
,将此数据存储在哈希%emp
中 以lastnames的升序排序顺序显示用户数据。
我假设姓氏是独一无二的
my $name;
print "enter name:\n";
while ( my $name = lc <STDIN> ) {
chomp $name;
print "you entered: $name\n";
push @n, $name;
last if ( $name eq 'exit' );
$count++;
print "enter name :\n";
}
print "count = $count\n";
my $r = pop @n;
print "@n\n";
my ($key, $value) = split(' ', @n);
$emp{$key} = $value;
while ( my ( $key, $value ) = each %emp ) {
my $value;
print "$key :$value\n";
}
我想要代码修正。
答案 0 :(得分:0)
首先,警告 - 解析名称通常非常困难。下面的所有代码都严格假设每个名称由两个由空格分隔的单词组成。另请注意,如果没有检查,您完全可以让用户按预期输入他们的姓名。
您希望my ($key,$value) = split(' ',@n);
分割@n
的每个元素,并通过以下分配以某种方式创建整个哈希值。 split不适用于列表,但它需要一个字符串。但是,您可以使用map
my %emp = map { split } @names; # names must be [word space(s) word]
我将您的数组名称从@n
更改为@names
。 map
获取列表并一次将块{ }
中的代码应用于一个元素,并返回已处理的列表。这被分配给%emp
,因为哈希是一个列表,所以可以做什么。见perldata。
由于( if )每个split
生成两个元素,因此获得的散列具有正确的配对。此处split
使用其默认值,因此split
与split ' ', $_
相同,其中' '
表示任意数量的空格。
我重复警告,一般的名称不包含两个单词。所以上述内容在任何意义上都不稳健,但它是一种通用的技术。
更灵活的方法是遍历您的名单
my %emp;
foreach my $name (@names)
{
my ($first, $last) = split ' ', $name;
if ($first and $last) {
$emp{$last} = $first;
}
else {
# print a message, or store 'bad' name on an array
}
}
print "$_, $emp{$_}\n" for sort keys %emp;
您应该添加对提交的名称格式的彻底检查。作为一个提示,我添加了一个非常简短的检查,检查split
是否产生了(至少)两个单词。
您可以通过编写如何处理元素并将其放入块map
的例程来对my %emp = map { process_name($_) } @names;
执行相同的操作。但是,错误处理将更加困难。
鉴于需要检查用户输入,最好在上面的循环中处理名称,但在输入时,如果格式错误,可以再次提示用户。
答案 1 :(得分:0)
my @n;
loop: while(1) { # get your data with while named as "loop"
print "enter name: ";
chomp(my $i = <STDIN>);
last loop if ($i eq "exit"); # enter to break the "loop"
push @n, lc $i
}
printf "count = %d\n", $#n + 1;
my %emp = map {
# split by space and get only first and secound
my @p = (split)[0,1];
# check here if everything is defined
if (defined $p[0]) {
# add this as key and value
@p
} else {
# skip (this part is important)
()
}
} @n; # converted to hash
my $p = {%emp}; # converted to {hash}ref
甚至
my %emp;
while(1) {
print "enter name: ";
chomp(my $i = <STDIN>);
last if ($i eq "exit");
my ($k, $v) = split q{ }, lc $i;
defined $k
and defined $v
and $emp{$k} = $v;
}
printf("count = %d\n", scalar keys %emp);