【问题标题】:Perl - can't use string (...) as an array refPerl - 不能使用字符串(...)作为数组引用
【发布时间】:2014-10-30 12:03:17
【问题描述】:

我正在使用来自 codeeval.com 的挑战练习 Perl,但遇到了意外错误。目标是逐行遍历文件,其中每一行都有一个字符串和一个用逗号分隔的字符,并找到该字符在字符串中最右边的位置。我得到了错误的答案,所以当我收到以下错误时,我更改了代码以仅打印出变量值:

Can't use string ("Hello world") as an ARRAY ref while "strict refs" in use at char_pos.pl line 20, <FILE> line 1.

我的代码如下。您可以在标题中查看文件中的示例。您还可以看到原始输出代码,它错误地只显示每个字符串中最右边的字符。

#CodeEval challenge: https://www.codeeval.com/open_challenges/31/
#Call with $> char_pos.pl numbers
##Hello world, d
##Hola mundo, H
##Keyboard, b
##Connecticut, n

#!/usr/bin/perl
use strict;
use warnings;

my $path = $ARGV[0];

open FILE, $path or die $!;

my $len;

while(<FILE>)
{
    my @args = split(/,/,$_);
    $len = length($args[0]) - 1;
    print "$len\n";
    for(;$len >= 0; $len--)
    {
        last if $args[0][$len] == $args[1];
    }


    #if($len > -1)
    #{
    # print $len, "\n";   
    #}else
    #{
    # print "not found\n";   
    #}

}

编辑: 根据下面的答案,这是我开始工作的代码:

#!/usr/bin/perl
use strict;
use warnings;
use autodie;


open my $fh,"<",shift;

while(my $line = <$fh>)
{
    chomp $line;
    my @args = split(/,/,$line);
    my $index = rindex($args[0],$args[1]);

    print $index>-1 ? "$index\n" : "Not found\n";
}

close $fh;

【问题讨论】:

  • 检查perldoc substr而不是$args[0][$len],如果您要比较字符串,请使用eq
  • 并使用while (&lt;&gt;) { … }而不是显式打开文件等;它是更惯用的 Perl。当您检查文档时(注意它需要是perldoc -f substr 才能按名称查找函数substr),请查找perldoc -f rindex。您可能希望在 /, */ 上进行拆分,以便在尾随字母之前留出空格。
  • 提示:您可能更喜欢my ($word, $letter) = split(/,/,$_);@args 是一个相当糟糕的名字。
  • 我也倾向于避免在split 中使用$_split ( /,/ ); 会做同样的事情。
  • @ikegami - 我喜欢这种拆分方法。将来我会牢记这一点。谢谢!

标签: arrays string perl file-io


【解决方案1】:

perl 中的字符串是一种基本类型,而不是可下标的数组。您可以使用 substr 函数从它们中获取单个字符(也只是字符串)或子字符串。

还要注意字符串比较是用eq完成的; == 是数值比较。

【讨论】:

    【解决方案2】:

    看来您需要对 Perl 函数有所了解。 Perl 有许多用于字符串和标量的函数,但并非总是能够一目了然。

    然而,Perl 有一个很棒的函数,叫做rindex,它完全可以满足你的需求。你给它一个字符串,一个 substring(在这种情况下,一个字符),它会从 right 字符串的一侧(index 从左侧执行相同的操作。)

    既然您正在学习 Perl,最好买几本关于现代 Perl 和标准编码实践的书籍。这样,您就可以了解更新的编码技术和标准的编码实践。

    这是一个示例程序:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use autodie;
    use feature qw(say);
    
    open my $fh, "<", shift;
    
    while ( my $line = <$fh> ) {
        chomp $line;
        my ($string, $char) = split /,/, $line, 2;
        if ( length $char != 1 or not defined $string ) {
            say qq(Invalid line "$line".);
            next;
        }
        my $location = rindex $string, $char;
        if ( $location != -1 ) {
            say qq(The right most "$char" is at position $location in "$string".);
        }
        else {
            say qq(The character "$char" wasn't found in line "$line".)";
    }
    close $fh;
    

    一些建议:

    • use autodie 允许你的程序在错误的open 上自动死掉。无需检查。
    • 三参数open 声明现在被认为是必要的。
    • 对文件句柄使用标量变量。它们更容易传递到子例程中。
    • 对循环使用词法范围的变量。尽量避免使用$_
    • 阅读后始终发送chomp

    最重要的是,错误检查!我检查了行的格式以确保只有一个逗号,并且我正在搜索的字符是一个字符。我还检查了rindex 的退出值,以确保它找到了该字符。如果rindex 没有找到该字符,则返回-1

    还知道一行中的第一个字符是0 而不是1。您可能需要为此调整,具体取决于您期望的输出。

    【讨论】:

    • 这很棒。感谢您的详尽回答!我会确保检查这些资源。 Perl 不是我最喜欢的语言,但有清晰、详细的解释会很有帮助。
    【解决方案3】:
    while($i=<DATA>){
    ($string,$char)=split(",",$i);
    push(@str,$string);}
    @join=split("",$_), print "$join[-1]\n",foreach(@str);
    
    
    
    __DATA__
    Hello world, d
    Hola mundo, H
    Keyboard, b
    Connecticut, n
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-18
      • 2023-03-31
      • 2020-05-22
      • 2019-06-11
      • 2022-01-15
      • 2018-04-06
      • 2020-02-21
      • 1970-01-01
      相关资源
      最近更新 更多