2014-09-05 46 views
3

我正在从codeeval.com的挑战练习Perl,我得到一个意外的错误。我们的目标是逐行遍历一个文件,其中每行都有一个字符串和一个用逗号分隔的字符,并在该字符串中查找该字符的最右侧。我得到错误的答案回来,所以我改变了代码打印出来只是变量值,当我得到了以下错误: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; 
+5

如果您正在比较字符串,请检查'perldoc substr'而不是$ $ args [0] [$ len]'并使用'eq'。 – 2014-09-05 13:54:45

+0

并使用'while(<>){...}'而不是明确地打开文件等;它更习惯Perl。当你检查文档时(注意它需要'perldoc -f substr'来查找函数'substr'的​​名字),查找'perldoc -f rindex'。您可能希望在'/,* /'上进行分割,以便在尾部的字母之前留出空格。 – 2014-09-05 14:09:42

+1

提示:您可能更喜欢'我的($字,$字母)=拆分(/,/,$ _);'。 '@ args'是相当可怜的名字。 – ikegami 2014-09-05 15:17:34

回答

3

看起来您需要了解一些关于Perl函数的知识。 Perl对字符串和标量有很多功能,并不总是可以从头开始知道它们。

但是,Perl有一个很棒的功能叫做rindex,它完全符合你的要求。你给它一个字符串,一个(在这种情况下,单个字符),它看起来对于子从字符串侧的第一位置(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陈述现在被认为是必要的。
  • 对文件句柄使用标量变量。他们更容易通过子程序。
  • 使用词法作用域变量for循环。尽量避免使用$_
  • 阅读后总是执行chomp

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

也知道一行中的第一个字符是0而不是1。你可能需要调整这取决于你期望的输出。

+0

这太好了。感谢您的彻底解答!我会确保查看这些资源。 Perl不是我最喜欢的语言,但它有助于清晰,详细的解释。 – 2014-09-05 16:34:54

3

字符串在Perl是一个基本的类型,而不是标化的阵列。您可以使用substr函数来获取单个字符(它们也只是字符串)或它们的子字符串。

另请注意,字符串比较是用eq; ==是数字比较。

0
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 
相关问题