Anirban Adhikary wrote:
> Dear List
> I have write the The following code to check a file and print only distinct
> lines to a new file and skips the duplicate lines. My source file is as
> follows
> 
> hello how are you?
> hello how are you?
> What language did you want to use?
> What language did you want to use?
> I am here
> You are there
> this is my first perl script
> What language did you want to use?
> 
> ###############################################################################
> my code is as follows
> 
> 
> #use strict;
> #use warnings;

Never comment out these lines - they help enormously to find simple errors.

> print "Enter the Absolutepath of the file\t";
> my $input=<STDIN>;
> chomp($input);
> 
> dup($input);
> 
> sub dup
> {
>   my $filename=shift;
>   my $count=0;
>   my @arr;
>   my $el;
>   my $element;

- Variables should be declared as close as possible to their point of first use.

- Try to use meaningful variable names; the @ in @arr means 'array' so you have
something called "array arr". Also the difference between the function of $el
and $element isn't clear from their names.

>   open(FH,"$filename");
>   while(<FH>)

- You must always check whether a file open succeeded.

- $filename should stand on its own. Read the perlfaq article

    perldoc -q quoting

  entitled What's wrong with always quoting "$vars"?

- The three-parameter form of open and lexical file handles are preferred, like 
this

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

>     {
>       chomp($_);
>       $element = $_;
>       if($count ==0)
>        {
>          push(@arr,$element);
>          $count+=1;
>          print "Count is $count\n";

$count isn't a count, as it is only incremented when it is zero and never used
thereafter. You also don't need it at all, so you can remove this if statement
altogether.

>        }
>       else
>        {
>          foreach $el(@arr)
>           {
>             my $len=$#arr;

$len is the index of the last element of @arr, not its length. Use

  my $len = @arr;

to get that.

>             chomp($el);

The strings were chomped before they were added to @arr so there is no need to
do it again.

>            # print "$element\n";
>             #print "The length of arr is $len\n";
>             if($el ==  $element)

The == operator is for comparing numbers; to compare strings you must use
eq. This is why your elsif block wasn't being executed: the values are being
forced to numbers before they are compared, and since non-numeric strings
evaluate as zero they were always numerically equal.

If you had left warnings enabled you would have a message to tell you this.

>              {
>                print "\t######Inside If######\t\n";
>                print $element."\n";
>                next;
>                #push(@arr,$_);
>              }
> 
>             elsif($el != $element)


There is no need to test again. If

  $el eq $element

failed, then

  $el ne $element

must succeed, and you need only an 'else' here.

>              {
>                push(@arr,$element);

You shouldn't modify an array that you're currently iterating over, as the
results aren't guaranteed and anything may happen. In other words, don't write

  foreach (@arr) {
      :
    push @arr, $val;
      :
  }

>                print "\t########Inside Elseif\n";
>                #next;
>              }
>           }
>        }

- The braces aren't paired properly in your program. I presume an extra one
belongs here.

- You test each new line again /every/ element in @arr, and push the line onto
the array /every time/ it finds an array element that doesn't match. I assume
you want to push the new line onto the array only if none of the elements match?
Something like this perhaps

  while (my $element = <$fh>) {

    chomp $element;

    my $found;

    foreach my $el(@arr) {
      if ($el eq $element) {
        $found++;
        last;
      }
    }

    if (not $found) {
      print "$element\n";
      push @arr,$element;
    }
  }

>  }
> 
> ###############################################################
> The problems I am facing are
> 
> 1) The code is not getting entered into elsif block
> 
> 2) I am comparing between 2 strings but if I use "eq" or "ne"  for
> comparison I am getting some horrible output so I am using numeric
> comparison.
> 
> 3)If I am giving print the $element variable outside foreach loop it is
> getting printed but Inside foreach loop it is not showing anything.
> 
> Can anybody Please suggest me where I am making the mistake?

HTH,

Rob

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to