我正在尝试编写一个脚本来计算用户在STDIN中输入的行数,字数和字符数。使用下面的脚本,我可以在用户将文件作为CLI输入时完成此操作,但是当我尝试将此代码用于STDIN时,我最终会得到一个无限循环。我应该改变什么才能解决这个问题?
print "Enter a string to be counted";
my $userInput = <STDIN>;
while ($userInput) {
$lines++;
$chars += length ($_);
$words += scalar(split(/\s+/, $_));
}
printf ("%5d %5d %5d %10s", $lines, $words, $chars, $fileName);
答案 0 :(得分:4)
您的程序很好,希望您需要从while
测试中的文件句柄中读取。目前您只是从STDIN读取一行,并反复检查它是 true - 即不是零或undef
。
您的代码应如下所示
use strict;
use warnings;
my ($lines, $chars, $words) = (0, 0, 0);
print "Enter a string to be counted";
while (<STDIN>) {
++$lines;
$chars += length;
$words += scalar split;
}
printf "%5d %5d %5d\n", $lines, $words, $chars;
请注意,我仅使用length
代替length $_
,因为$_
是length
运算符的默认参数。 $_
只有在使用默认值时才真正发挥作用。
同样,split
的默认参数是split ' ', $_
,这是你想要的split /\s+/, $_
,因为如果有任何前导空格,后者会返回零长度的初始字段$_
。单个文字空间' '
的特殊值只是提取所有非空格字符序列,这几乎总是你想要的。除了一个空格之外的任何东西都会正常转换为正则表达式。
最后,我使用++$lines
代替$lines++
。后者很受欢迎只是因为C ++语言的名称,并且表达式返回的值必须是变量的原始值而不是 new < / em>一个。更常见的是,增量被用作自己的语句,就像这里返回的值无关。如果Perl没有优化它(因为上下文是无效的并且返回值未使用),代码将执行不必要的额外工作来保存变量的原始值,以便在增量之后返回它。我还认为++$var
看起来更像是命令式“increment $var
”,并提高了代码的可读性。
答案 1 :(得分:1)
您的输入必须在循环内。否则你一遍又一遍地处理相同的字符串。
答案 2 :(得分:1)
也许这就是你需要的东西?
use strict;
use warnings;
print "Enter a string to be counted:\n";
my $lines = 0;
my $chars = 0;
my $words = 0;
while (<>) {
chomp;
$lines++;
$chars += length ($_);
$words += scalar(split(/\s+/, $_));
}
printf ("lines: %5d words: %5d chars: %5d\n", $lines, $words, $chars);