簡體   English   中英

Perl:誰能告訴我如何解決這個警告

[英]Perl : Can anyone tell me how to resolve this warnings

代碼第 1 部分:

      my $length = @array;

269   for (my $j=1; $j <= $length; $j+=1) {
270
271     if ( $fields[$j] =~ /dat/) {
    
         }}

警告 1:

Use of uninitialized value within @array in pattern match (m//) at wrk.pl line 270

代碼第 2 部分:這里我試圖將十進制轉換為十六進制

70 while (my $line = <DATA>) {
71     $line =~ s/ '([0-9]*)' / sprintf '0x%x', $1/eg;
72     print OUT $line;
       }

警告 2:

Argument "" isn't numeric in sprint at wrk.pl line 71

更新

在我for (my $j=1; $j <= $#array; $j+=1)和第二個警告我更改$line =~ s/ '([0-9]+)' / sprintf '0x%x', $1/eg; .

我又收到兩個警告

代碼第 3 部分:這里我正在檢查每列中存在的最大字寬

my @col_lns;
while (<file>) {
  my @row = split " ",$_;
  @col_lns = map ((length) @rows) if $. ==1;

for ( my $col_l =0; $col_l <$#row; $col_l+=1) {
my $col_ln = length $row[$col_l];

  if ($col_lns[$col_l] < $coln)    ###Here I am getting warning
{
  $col_lns[$col_l] = $coln;
}
}

警告 3:

Use of uninitialized value in numeric lt (<) 

代碼第 4 部分

my $pack1 = substr($add,4,4);
my $pack2 = substr($add,0,4);

警告 4

Use of $add in substr
substr outside of string 

一步一步寫下代碼的演練。 (感謝池上在評論中提到了其中的一些內容)

代碼第 1 部分:

這部分有問題:

  • 您檢查數組@array的長度,然后使用該長度循環遍歷@fields數組。
  • 您從數組索引 1 開始,然后轉到等於數組長度的數組索引(假設使用了正確的數組長度)。 這是一次性錯誤。 數組從 0 開始。您應該從 0 循環到數組$#fields最大索引(比長度少一個)。
  • 警告 1 與代碼中寫入的內容不匹配。 錯誤應該是關於數組@fields ,這是您在代碼中使用的。
  • 警告 1 給出了錯誤的行號 270。(最后兩點表明您在復制錯誤消息后更改了代碼,這是一件壞事)
  • 警告 1 表示@array數組中的一個值未定義。 由於循環條件中存在一次性錯誤,因此可以很好地猜測未定義值位於數組的末尾,一旦修復循環條件,此警告就會消失。

代碼第 2 部分:

  • 您正在將空字符串""sprintf ,它會警告您這一點。 由於您的匹配項被空格和單引號包圍,因此輸入中可能是一個空字符串(即'' )。 為避免匹配,您可以使用+而不是* ,即[0-9]+ 量詞+表示“匹配 1 次或多次”,而*表示“匹配 0 次或多次”。 請注意,這樣做也會留下引號和空格,它們在其他時候會被刪除。
  • DATA是文件內DATA的保留文件句柄,使用文件底部的__DATA__標記。 除非這是您正在執行的操作,否則您應該選擇另一個文件句柄。 最好是一個詞法,例如my $fh

你進一步評論:

@ikegami,更改后仍然收到警告。

由於您沒有提及這些警告是什么,我們無法幫助您。

我認為將@array交換為@fields是一個錯字。

在這里,您可以獲得數組中的元素數:

my $length = @array;

因此,如果您的數組包含五個元素,則$length現在將包含 5。數組中的五個元素的索引為 0 到 4。

現在您遍歷數組的元素:

for (my $j=1; $j <= $length; $j+=1) {
  ...
}

顯然,我不知道你的數組中有什么,但是你從索引 1 開始看起來很奇怪 - 通常,你會從索引 0 開始。你的代碼一直持續到索引 5 - 但你的數組沒有有一個索引 5。正如我上面所說,你的索引從 0 到 4。

因此,您嘗試訪問索引 5 處的元素,但沒有這樣的元素,並且當您嘗試使用該值時會收到“未定義值”警告。

所以你的代碼應該是這樣的:

# Start at 0; continue only while $j is less than $length
for (my $j=0; $j < $length; $j+=1) {
  ...
}

但是,這不是編寫此代碼的一種非常“Perlish”的方式。 Perl 程序員很少使用這種“C 風格”的循環語法。 我們喜歡迭代一個值列表。

for my $j (0 .. $#array) {
  ..
}

這完全等同於您的原始代碼,但(在我看來)它更容易閱讀。

  • .. :這是“范圍運算符”。 它返回 0 到$#array之間的整數列表
  • $#array :每個數組都有一個與之關聯的特殊變量 ( $#arrayname ),其中包含數組中的最高索引號。 在這種情況下,這將是 4。

但我們可以改進這一點。 您實際上並不想要數組索引,對嗎? 你真正想要的是數組元素 你可以直接得到這些。

for my $element (@array) {
  if ($element =~ /dat/) {
    ..
  }
}

最后,Perl 程序員可能會在這里使用$_作為變量,因為您通常不需要實際編寫它:

for (@array) {   # stores each element in turn in $_
  if (/dat/) {   # checks regex against $_
    ...
  }
}

讓我們嘗試稍微更改 OP 的代碼以制作可行的代碼示例。

注意 #1:OP 沒有提供輸入數據樣本

注意:#2: s/ '([0-9]+)' /sprintf ' 0x%x ', $1/eg; 會更正確

use strict;
use warnings;
use feature 'say';

my @array = ( 'First sentence here', undef, 'Second dat sentence', undef, 'One more data sentence');

say '---- Part 1 ----';

for ( @array ) {
    if( defined $_ and /dat/ ) {
        say;
    }
}

say '---- Part 2 ----';

while ( <DATA> ) {
    s/ '([0-9]*)' /sprintf ' 0x%x ', $1/eg;
    print $_;
}

__DATA__
some test data placed here for a test
ok, lets put some digits '3824' bits
some more '8902' bytes some text
number of files '0x834' you did not account for this
now finish with '123456' number

輸出

---- Part 1 ----
Second dat sentence
One more data sentence
---- Part 2 ----
some test data placed here for a test
ok, lets put some digits 0xef0 bits
some more 0x22c6 bytes some text
number of files '0x834' you did not account for this
now finish with 0x1e240 number

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM