0

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

3 回答 3

4

您的程序很好,期望您需要从测试中的文件句柄中读取while。目前,您只是从 STDIN 读取一行并反复检查它是否为- 即不是零或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 $_as$_length运算符的默认参数。$_只有在您使用默认值时才会真正发挥作用。

同样,默认参数 tosplitsplit ' ', $_您想要的,split /\s+/, $_因为如果 . 中有任何前导空格,后者将返回零长度初始字段$_。单个文字空间的特殊值' '只是提取所有非空格字符序列,这几乎总是你想要的。除了单个空格之外的任何内容都将正常转换为正则表达式模式。

最后,我使用++$lines了而不是$lines++. 后者之所以流行只是因为 C++ 语言的名称,而且表达式返回的值需要是变量的原始值而不是值的情况不太常见。更多情况下,增量本身用作语句,就像这里一样,当返回的值无关紧要时。如果 Perl 没有优化它(因为上下文是 void 并且返回值未使用),代码将做不必要的额外工作来保存变量的原始值,以便在递增后返回它。我也认为++$var看起来更像是命令式的“增量$var,并提高了代码的可读性。

于 2014-05-11T12:40:48.677 回答
1

您的输入必须在循环内。否则,您将一遍又一遍地处理相同的字符串。

于 2014-05-11T12:16:21.547 回答
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);
于 2014-05-11T12:35:45.407 回答