简体   繁体   English

Perl - 不能使用字符串(...)作为数组引用

[英]Perl - can't use string (…) as an array ref

I'm practicing Perl with a challenge from codeeval.com, and I'm getting an unexpected error. 我正在用codeeval.com的挑战练习Perl,我遇到了意想不到的错误。 The goal is to iterate through a file line-by-line, in which each line has a string and a character separated by a comma, and to find the right-most occurrence of that character in the string. 目标是逐行遍历文件,其中每行包含一个字符串和一个用逗号分隔的字符,并在字符串中查找该字符的最右侧出现。 I was getting wrong answers back, so I altered the code to print out just variable values, when I got the following error: 我得到了错误的答案,所以当我收到以下错误时,我更改了代码以打印出变量值:

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

My code is below. 我的代码如下。 You can see a sample from the file in the header. 您可以在标题中看到该文件中的示例。 You can also see the original output code, which was incorrectly only displaying the right-most character in each string. 您还可以看到原始输出代码,该代码错误地仅显示每个字符串中最右侧的字符。

#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";   
    #}

}

EDIT: Based on the answers below, here's the code that I got to work: 编辑:根据下面的答案,这是我工作的代码:

#!/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;

Strings in perl are a basic type, not subscriptable arrays. perl中的字符串是基本类型,而不是可下载数组。 You would use the substr function to get individual characters (which are also just strings) or substrings from them. 您可以使用substr函数来获取单个字符(也只是字符串)或来自它们的子字符串。

Also note that string comparison is done with eq ; 还要注意字符串比较是用eq完成的; == is numeric comparison. ==是数字比较。

It looks like you need to know a bit about Perl functions. 看起来您需要了解Perl函数。 Perl has many functions for strings and scalars and it's not always possible to know them all right off the top of your head. Perl有许多用于字符串和标量的功能,并不总是可以直接了解它们。

However, Perl has a great function called rindex that does exactly what you want. 但是,Perl有一个很棒的函数叫做rindex ,可以完全按你的要求运行。 You give it a string, a substring (in this case, a single character), and it looks for the first position of that substring from the right side of the string (the index does the same thing from the left hand side.) 你给它一个字符串,一个子字符串 (在这种情况下,单个字符),它从字符串的右侧查找该子字符串的第一个位置( 索引从左侧做同样的事情。)

Since you're learning Perl, it may be a good idea to get a few books on Modern Perl and standard coding practices. 既然您正在学习Perl,那么获得一些有关Modern Perl和标准编码实践的书籍可能是个好主意。 This way, you know newer coding techniques and the standard coding practices. 这样,您就会了解更新的编码技术和标准编码实践。

Here's a sample program: 这是一个示例程序:

#!/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;

A few suggestions: 一些建议:

  • use autodie allows your program to automatically die on bad open . use autodie允许程序在open自动死亡。 No need to check. 无需检查。
  • Three parameter open statement is now considered de rigueur. 现在认为三个参数open语句是必要的。
  • Use scalar variables for file handles. 对文件句柄使用标量变量。 They're easier to pass into subroutines. 它们更容易传递到子程序中。
  • Use lexically scoped variables for loops. 使用词法范围的变量进行循环。 Try to avoid using $_ . 尽量避免使用$_
  • Always do a chomp after a read. 阅读后总是做一个chomp

And most importantly, error check ! 最重要的是, 错误检查 I check the format of the line to make sure that's there is only a single comma, and that the character I'm searching for is a character. 我检查行的格式以确保只有一个逗号,并且我正在搜索的字符是一个字符。 I also check the exit value of rindex to make sure it found the character. 我还检查rindex的退出值,以确保它找到了该字符。 If rindex doesn't find the character, it returns a -1 . 如果rindex找不到该字符,则返回-1

Also know that the first character in a line is 0 and not 1 . 还要知道一行中的第一个字符是0而不是1 You may need to adjust for this depending what output you're expecting. 您可能需要根据您期望的输出进行调整

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM