2014-09-05 83 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 
相關問題