2015-07-08 2 views
0

Здесь мы ищем строку «reftext» в данном файле. Строка рядом с ней содержит строку с 3 целыми числами. Поэтому мы извлекаем их в @all_num. Мы печатаем значение @all_num[2] только в том случае, если оно не является NULL. Но логика здесь используется не печатает @all_num[2], даже если он имеет 0.Как отличить «0» от NULL в perl?

#!/usr/bin/perl 
open(READFILE, "<myfile.txt"); 
@list  = <READFILE>; 
$total_lines = scalar @list; 

for ($count = 0; $count < $total_lines; $count++) { 
    if (@list[ $count =~ /reftext/) 
     { 
      @all_num = @list[ $count + 1 ] =~ /(\d+)/g; 
      if (@all_num[2] != NULL) { 
       print "@all_num[2]\n"; 
      } 
    } 
} 
+6

Используйте 'use strict' и' используйте предупреждения' в верхней части вашей программы после строки _shebang_. – serenesat

+2

И было бы более полезно, если вы можете предоставить данные _myfile.txt_. – serenesat

+4

В Perl нет NULL. Используйте undef, когда вы имеете в виду «no value». –

ответ

0

Попробуйте это:

#!/usr/bin/perl 
use warnings; 
use strict; 

open(READFILE, "<", "myfile.txt") or die $!; 
my @list = <READFILE>; 
my $total_lines = scalar @list; 
close (READFILE); 

for(my $count=0; $count<$total_lines; $count++) 
{ 
    if($list[$count] =~ /reftext/) 
    { 
     my @all_num = $list[$count+1] =~ /(\d+)/g; 
     if($all_num[2] ne '') 
     { 
      print "$all_num[2]\n"; 
     } 
    } 
} 

Для проверки переменной равно нулю или нет:

if ($str ne '') 
{ 
    print $str; 
} 

или лучше:

my ($str); 
$str = ""; 
if (defined($str)) 
{ 
    print "defined"; 
} 
else 
{ 
    print "not defined"; 
} 
+0

Использование OP всех шапок «NULL» предлагает мне, что он предназначен для NULL в стиле SQL, и в этом случае тестирование для пустых строк является неправильным, поскольку пустая строка - это значение, а SQL NULL - это отсутствие значения (похожее по понятию на Perl 'undef', но с другой семантикой правды). –

+0

@DaveSherohman: Да, вы правы. Именно по этой причине я попросил ввести данные. Я жду комментария OP. – serenesat

+1

Могу ли я предложить - я думаю, что ваш образец кода будет улучшен с помощью 3 arg open с лексическим дескриптором файла. – Sobrique

2

Надеюсь, что это помогает,

use strict; 
use warnings; 

my @fvals = (
[ i => undef ], 
[ j => 0 ], 
[ k => "" ], 
); 

for my $r (@fvals) { 
    my ($k, $v) = @$r; 
    if (!defined($v)) { print "$k is undef\n"; } 
    elsif (!length($v)) { print "$k is empty string\n"; } 
    # elsif (!$v)  { print "$k is zero\n"; } 
    # recognizes zero value in "0.0" or "0E0" notation 
    elsif ($v == 0)  { print "$k is zero\n"; } 
} 

выход

i is undef 
j is zero 
k is empty string 
+0

Если нуль всегда '0', вы можете' if (определено $ v и $ v eq "0") ..' –

4

Perl не включают NULL, поэтому линия

if(@all_num[2]!= NULL) 

бессмысленна в Perl. (Точнее, он пытается найти sub с именем NULL и запустить его, чтобы получить значение для сравнения с @all_num[2], но не может этого сделать, потому что вы (предположительно) не определили такой sub.) Обратите внимание, что если вы включили use strict, это приведет к фатальной ошибке вместо того, чтобы притворяться, что работает. Это одна из причин, почему всегдаuse strict.

Side Примечание: Когда вы тянете значение из массива, это только одно значение, так что вы должны сказать $all_num[2], а не @all_num[2] когда речь идет о третьем элементе массива @all_num. (Да, это немного запутывает, чтобы привыкнуть. Я слышал, что он был изменен в Perl 6, но я предполагаю, что вы используете Perl 5 здесь.) Обратите внимание, что если вы включили use warnings, он сказал бы вы, что «Скалярное значение @all_num [2] лучше написано как $ all_num [2]». Это одна из причин, почему всегдаuse warnings.

Если вы хотите, чтобы проверить, содержит ли $all_num[2] значение, надлежащим образом выразить, что в Perl является

if (defined $all_num[2]) 
+0

Спасибо за предложения. – user3477363

2

Это как ваша программа будет выглядеть, используя лучшие практики

Вы должны

  • Всегда use strict и use warnings и объявляйте все свои переменные my

  • Используйте трехпараметрической форму open

  • Убедитесь, что open вызовов удались, и включают в себя $! в die строке, если не

  • Используйте while цикл для обработки файла на одну строки время, в предпочтении читать весь файл в память

#!/usr/bin/perl 

use strict; 
use warnings; 

open my $fh, '<', 'myfile.txt' or die $!; 
while (<$fh>) { 

    next unless /reftext/; 

    my $next_line = <$fh>; 
    my @all_num = $next_line =~ /\d+/g; 
    print "$all_num[2]\n" if defined $all_num[2]; 
} 
0

Если другие ответы не работают, попробуйте обрабатывать переменный как строка:

if ($all_num[2] == 'null' && length($all_num[2]) == 4){ 
    # null 
} else { 
    # not null 
} 

Как и с любым кодом, который вы пишете, не забудьте проверить ваш код.

Смежные вопросы