如何在不使用wc的情况下使用perl计算STDIN中的字符?

时间:2014-05-11 12:14:23

标签: perl loops count wc

我正在尝试编写一个脚本来计算用户在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);

3 个答案:

答案 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);