Perl: Alguém pode me dizer como resolver esses avisos
Parte 1 do código:
my $length = @array; 269 for (my $j=1; $j <= $length; $j+=1) { 270 271 if ( $fields[$j] =~ /dat/) {
}}
Aviso 1:
Use of uninitialized value within @array in pattern match (m//) at wrk.pl line 270
Parte do código 2: Estou tentando converter o decimal em hexadecimal
70 while (my $line = <DATA>) {
71 $line =~ s/ '([0-9]*)' / sprintf '0x%x', $1/eg;
72 print OUT $line;
}
Aviso 2:
Argument "" isn't numeric in sprint at wrk.pl line 71
Atualizar
Os dois avisos acima agora foram resolvidos após eu colocar e para o segundo aviso eu alterar .for (my $j=1; $j <= $#array; $j+=1)$line =~ s/ '([0-9]+)' / sprintf '0x%x', $1/eg;
Estou recebendo mais dois avisos
Parte do código 3 : Aqui estou verificando a largura máxima da palavra presente em cada coluna
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;
}
}
Aviso 3:
Use of uninitialized value in numeric lt (<)
Código parte 4 ;
my $pack1 = substr($add,4,4);
my $pack2 = substr($add,0,4);
Aviso 4
Use of $add in substr
substr outside of string
Respostas
Escrevendo passo a passo o passo a passo do código. (Crédito a ikegami por mencionar algo disso nos comentários)
Parte 1 do código:
Coisas erradas com esta parte:
- Você verifica o comprimento do array e
@array, em seguida, usa esse comprimento para percorrer o@fieldsarray. - Você começa no índice de array 1 e vai para o índice de array igual ao comprimento do array (assumindo que o comprimento correto do array foi usado). Este é um erro único. As matrizes começam em 0. Você deve fazer um loop de 0 ao índice máximo da matriz
$#fields(um a menos que o comprimento). - Aviso 1 não corresponde ao que está escrito no código. O erro deve ser sobre array
@fields, que é o que você usa no código. - O Aviso 1 fornece o número de linha incorreto 270. (Esses dois últimos pontos indicam que você alterou o código após copiar a mensagem de erro, o que é uma atitude inadequada)
- Aviso 1 significa que um valor na
@arraymatriz é indefinido. Como você tem um erro único nas condições do loop, um bom palpite é que o valor indefinido está no final da matriz e que esse aviso desaparece assim que você corrige a condição do loop.
Parte do código 2:
- Você está alimentando o string vazio
""parasprintf, e ele o avisa sobre isso. Uma vez que sua correspondência está cercada por espaço e aspas simples, é provável que seja uma string vazia na entrada (ou seja''). Para evitar a correspondência, você pode usar em+vez de*, ie[0-9]+. O quantificador+significa "corresponder 1 ou mais vezes", enquanto*significa "corresponder 0 ou mais vezes". Esteja ciente de que isso também deixará aspas e espaços, que são removidos em outras ocasiões. DATAé um identificador de arquivo reservado para dados no arquivo, usando o__DATA__marcador na parte inferior do arquivo. A menos que seja isso que você está fazendo, você deve escolher outro identificador de arquivo. De preferência um léxico, por exemplomy $fh.
Você comenta mais:
@ikegami, ainda recebendo avisos após as mudanças.
Já que você não mencionou quais são esses avisos, não podemos ajudá-lo.
Presumo que trocar @arraypara @fieldsé um erro de digitação.
Aqui, você obtém o número de elementos em sua matriz:
my $length = @array;
Portanto, se sua matriz contém cinco elementos, $lengthagora conterá 5. Os cinco elementos em sua matriz terão os índices de 0 a 4.
Agora você percorre os elementos de sua matriz:
for (my $j=1; $j <= $length; $j+=1) {
...
}
Obviamente, não sei o que está em seu array, mas parece estranho que você esteja começando no índice 1 - normalmente, você começaria no índice 0. E seu código continua até o índice 5 - mas seu array não tem um índice 5. Como eu disse acima, seus índices vão de 0 a 4.
Então, você tenta acessar o elemento no índice 5, não existe tal elemento e você obtém um aviso de "valor indefinido" quando tenta usar esse valor.
Portanto, seu código provavelmente deve ser assim:
# Start at 0; continue only while $j is less than $length
for (my $j=0; $j < $length; $j+=1) {
...
}
No entanto, essa não é uma maneira muito "pervertida" de escrever esse código. Os programadores Perl raramente usam esta sintaxe de loop "estilo C". Gostamos de iterar em uma lista de valores.
for my $j (0 .. $#array) {
..
}
Isso é exatamente equivalente ao seu código original, mas (na minha opinião) é muito mais fácil de ler.
..: Este é o "operador de alcance". Ele retorna uma lista de inteiros entre 0 e$#array$#array: Cada array possui uma variável especial ($#arrayname) associada a ela que contém o número de índice mais alto do array. Nesse caso, será 4.
Mas podemos melhorar isso. Você realmente não quer os índices de array, quer? O que você realmente quer são os elementos do array . E você pode obtê-los diretamente.
for my $element (@array) {
if ($element =~ /dat/) {
..
}
}
Finalmente, um programador Perl provavelmente usaria $_como a variável aqui, já que você geralmente não precisa realmente escrevê-la:
for (@array) { # stores each element in turn in $_ if (/dat/) { # checks regex against $_
...
}
}
Vamos tentar mudar um pouco o código do OP para fazer um exemplo de código viável.
Nota # 1: nenhuma amostra de dados de entrada fornecida pelo OP
Nota: # 2: s/ '([0-9]+)' /sprintf ' 0x%x ', $1/eg;seria mais correto
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
Resultado
---- 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