qsl has asked for the wisdom of the Perl Monks concerning the following question:

Monks,
I am having a file,the contents are like,
....... First Name ....... ....... Last Name ......
I have to check "First Name" is present first in the file and "Last Name" is present second in the file.i.e if LastName comes,first and First Name comes second,I have to give error message.My code is,
open fhand,file.txt; while(<fhand>}{ if($_ =~/First Name/){ $First =1; } if($_ =~/Last Name/){ print"proceed" if($First = 1); }else{ print"Order is not correct\n"; }
But it is not giving the exact output.Monks any solution for this.

Replies are listed 'Best First'.
Re: File reading
by GrandFather (Saint) on Jun 27, 2006 at 11:21 UTC

    It is important to use copy and paste to post your code otherwise we end up chasing transcription errors. In this case while(<fhand>}{ is bad syntax and is probably a transcription error. But what about if($First = 1); (assign 1 to $first - the test is always true)? Transcription error or bug?

    You should always add use strict; use warnings; to your code. They will catch many silly mistakes. In this case both the errors pointed out above would have been caught.

    Of less importance in ($_ =~/ the $_ =~ is redundant.

    You don't actually provide any test data and you don't say under what circumstances the result is incorrect. The followign code should serve as a starting point for elaborating on the actual problem you are having:

    use strict; use warnings; while (<DATA>) { next if (m/First Name/ .. m/Last Name/); next if ! m/Last Name/; print "Order is not correct\n"; last; } __DATA__ ....... Last Name ...... ....... First Name .......

    Prints:

    Order is not correct

    DWIM is Perl's answer to Gödel
    A reply falls below the community's threshold of quality. You may see it by logging in.
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: File reading
by davorg (Chancellor) on Jun 27, 2006 at 11:13 UTC
    print"proceed" if($First = 1);

    You probably mean:

    print"proceed" if($First == 1);
    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: File reading
by Moron (Curate) on Jun 27, 2006 at 12:10 UTC
    davorg has correctly identified where the bug lies. 'if ( $first = 1 )' will assign 1 to $first and then submit the same as the value of the 'if' condition (1 being a true value). But there are some things which should become habitual, even when writing the first version:
    #!/usr/bin/perl use strict; # avoid typos and unclear scoping... use warnings; # ...amongst other things # open fhand,file.txt; # this will now cause the # compilation error that it should # ...replacement further down... # declare and init your vars, including file handles my $file = 'file.txt' my $path = $ENV{ SOME_PATH } . '/' . $file; # or must cd? open my $fh, "<$path" or warn "$!: $file\n" and exit $?; # assume I/O can and will go wrong sometimes my $first = 0; while( <$fh> ){ # indent your nests for clarity # avoid falling thru from one case into the next if ( /First Name/ ) { $first = 1; # any other processing of First name line } elseif ( /Last Name/ ) { $first or die "Order is not correct\n"; # any other processing of Last name line } elsif ( 0 ) { # ...etc.... else { # default or 'all other' case if applicable } } close $fh; # specifically close filehandles

    -M

    Free your mind

Re: File reading
by johngg (Canon) on Jun 27, 2006 at 13:09 UTC
    If you slurp the file into a string you can use a regular expression look-ahead to make sure the file contains "First Name" and "Last Name" in the right order.

    use strict; use warnings; my $fileText; do {local $/; $fileText = <DATA>}; my $rxOK = qr {(?xms) ^First\sName (?=.*?^Last\sName) }; print $fileText =~ $rxOK ? qq{File OK\n} : qq{File BAD\n}; __END__ ..... First Name ..... ..... Last Name .....

    This seems to be working for all of the failure cases I can think of. I hope it is of use.

    Cheers,

    JohnGG

    Update: To cope with multiple occurences of "First Name" or "Last Name" in the file you could insert the following after reading the file.

    my $fCnt = $fileText =~ /First\sName/g; die qq{"First Name" occurs more than once\n} if $fCnt > 1; my $lCnt = $fileText =~ /Last\sName/g; die qq{"Last Name" occurs more than once\n} if $lCnt > 1;
    Update 2: That last update was cobblers, it doesn't work properly. Whoops ;(

    Update 3: Should have assigned to a list, not a scalar.

    my @fCnt = $fileText =~ /First\sName/g; die qq{"First Name" occurs more than once\n} if @fCnt > 1; my @lCnt = $fileText =~ /Last\sName/g; die qq{"Last Name" occurs more than once\n} if @lCnt > 1;
A reply falls below the community's threshold of quality. You may see it by logging in.
A reply falls below the community's threshold of quality. You may see it by logging in.