我正在尝试打开文件,扫描它,并让程序打印出正数,负数和零数。我有程序成功打开文件,但找到“频率”是给我带来麻烦的。我在上课的那天病了,似乎无法找到与我的具体提示相关的帮助。以下是我到目前为止的情况:
#!/usr/bin/perl
use strict;
use warnings;
my ( $ctrZ ) = ( 0 );
while( my $num = <DATA> ) {
chomp($num);
## print "num=[$num]\n";
if ( $num =~ /^-\d+$/ ) {
$ctrZ++;
}
printf("freq(0):%9s\n", $ctrZ );
exit;
__DATA__
19
-22
498
512
15
-932
0
22
808
17
-32
注意:我们的教授给了我们一个文件供我们使用。它是一个.txt文件,每行都有一个数字。
答案 0 :(得分:1)
您的代码存在一些问题,但主要问题是:
if ($infile) {
$Pos_Int++;
$Neg_Int++;
$Zer_Int++;
}
那只是评估文件名$infile
的内容。它永远是真的,因此你总是将所有的计数器增加一个。
所以你在这里所做的一切基本上是计算线条。
我还建议,你不需要:
open(FHIN, '<', $infile); #Opens the file prompted by user.
my @lines = <FHIN>; #Variable storing the number of lines in the file.
chomp( @lines );
close(FHIN);
打开文件,将其读入数组,然后迭代数组?
为什么不用while循环逐行(它也使用更少的内存)。
另外 - 好的风格是使用词法文件句柄而不是大写名称,这是全局范围。
所以:
open ( my $input, '<', $infile ) or die $!; #check return code for errors.
while ( my $line = <$input> ) { #iterate the input line by line, setting $_ for each.
$Pos_Int++ if $line > 0;
$Neg_Int++ if $line < 0;
$Zer_Int++ if $line == 0;
}
应该做的伎俩 - 但请记住它不做任何输入验证。如果有必要,正则表达式可以帮助那里。
此外:
if (-e $infile) { #If the file can't be found, it will exit.
} else {
print ("No such file exists. Program closing.\n");
exit;
}
这是多余的,因为您可以 - 并且应该 - 从open
捕获返回代码。如果你这样做,那么你会发现其他条件,如文件不可读,或者是一个破损的符号链接或一堆其他问题。
E.g。
open ( my $input, '<', $infile ) or die "Problem opening file: $!";
$!
会给你一个更有意义的错误代码 - 它会告诉你'没有这样的文件或目录'和'权限被拒绝'之间的区别。
答案 1 :(得分:-1)
您可以使用<=>
运算符来准确获取所需内容。根据{{3}}:
二进制“
<=>
”返回-1,0或1,具体取决于左侧 参数在数值上小于,等于或大于右 参数。
所以:
$ perl -MData::Dumper -wne '$count{$_ <=> 0}++; END { print Dumper(\%count); }' numbers.txt
假设 numbers.txt 包含以下内容:
111
0
-892
-664
21
0
63
868
-351
-263
467
-58
625
724
0
0
990
107
-739
-501
-386
909
-96
0
-735
输出将是:
$VAR1 = {
'0' => 5,
'1' => 10,
'-1' => 10
};