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

I am trying to find the length of the line in below code but the output is not correct

#!/usr/bin/perl open $fb, "myfilename.txt"; while ($line=<$fb>) { chomp($line); if ($.=<>){ print length "$line"; } }

below is my file which I am reading

heaven heavenly heavenns abc heavenns heavennly

now when script read the file and I want to know the length of 4th line but the output is not correct it show 6 but the expected is 3

Replies are listed 'Best First'.
Re: how to find the length of any line of file
by Corion (Patriarch) on Nov 22, 2017 at 09:18 UTC

    Can you show us three lines of input and show us the output you get, and why you think it is not correct?

    It helps us to give you advice that is more to the point if you show us the input and output, and tell us why you think it's not correct.

    Also, maybe consider explaining what the following part of your code is supposed to do:

    if ($.=<>){ print length "$line"; }

    Good general advice would be to allow Perl to tell you about problematic parts in your program. The warnings pragma enables that. Add the following line to the top of your program (before the open line):

    use warnings;
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: how to find the length of any line of file
by Discipulus (Canon) on Nov 22, 2017 at 10:19 UTC
    Hello lakshmikant,

    First please follow the advice Corion said above: use warnings; and also add use strict; line. Notice that if warnings are not clear to you you can temporarly add use diagnostics;

    As already said the if ($.=<>) is confusing and probably nonsense: with = you are assigning to $. what the diamond operator <> is spitting out!

    See the diamond operator explained to know it better.

    In a check, when you would say "if this is equal to that" you must use == for numbers and eq for strings.

    Improve your code with suggestions received until now and see what it happens; then feel free to reply to this threads for more questions.

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: how to find the length of any line of file
by thanos1983 (Parson) on Nov 22, 2017 at 11:45 UTC

    Hello lakshmikant,

    One possible way to get the length of a string is using the length function. I would also recommend to use warnings and strict as the fellow Monks already proposed. Also when opening and closing files use die or warn, read the links on why and how to use them.

    Also when you open a file use the MODE for reading e.g. '<'.

    Sample of solution to your problem including all the minor recommendations:

    #!/usr/bin/perl use strict; use warnings; use feature 'say'; my $file = 'myfilename.txt'; open my $fb, "<", $file or die "Can not open '$file': $!"; while (my $line=<$fb>) { chomp $line; say 'Line: ' . $line . ' Length: ' . length $line; } close $fb or warn "Can not close '$file': $!"; __END__ $ perl test.pl Line: heaven Length: 6 Line: heavenly Length: 8 Line: heavenns Length: 8 Line: abc Length: 3 Line: heavenns Length: 8 Line: heavennly Length: 9

    Update: You should read about the perlvar/SPECIAL-VARIABLES regarding the $. variable that you are using on your script. Maybe you do not understand yet exactly how it works or what is it for.

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: how to find the length of any line of file
by 1nickt (Canon) on Nov 22, 2017 at 14:37 UTC

    Hi, welcome. Regarding your code:

    #!/usr/bin/perl #<--------------------------# Where are 'use strict;', 'use warnings;' +? open $fb, "myfilename.txt"; # What if the file is missing? while ($line=<$fb>) # What if you forgot you're using $line el +sewhere? { #<------------------# Perl ignores whitespace but why be messy +? chomp($line); if ($.=<>){ # `=` is not a comparison operator! print length "$line"; # ^---------# ... and then a newline character? } # Odd indentation makes it hard to tell wh +at this matches. #<----------------------# Perl ignores whitespace but why be messy +? }

    Here is a cleaned up version. I trust you to do the work of looking up the documentation for things you don't recognize, so that you learn why it's better to do it as I've shown. (But not the only way, of course!)

    use strict; use warnings; use feature 'say'; # This section creates a temporary file for testing my $file = "/tmp/$0.txt"; open TMP, '>', $file or die "Died: $!"; print TMP for (<DATA>); close TMP; #-------------------------------------------------# print 'Which line would you like to measure? '; chomp( my $wanted = <STDIN> ); die 'Died: wanted line number required' if not $wanted; open my $FH, '<', $file or die "Died: $!"; while ( my $line = <$FH> ) { chomp $line; if ( $. == $wanted ) { say "The length of line $wanted ('$line') is " . length $line; last; } say "Reached end of file before line $wanted" if eof; } # remove the test file unlink $file; __DATA__ heaven heavenly heavenns abc heavenns heavennly

    Hope this helps!


    The way forward always starts with a minimal test.
Re: how to find the length of any line of file
by Laurent_R (Canon) on Nov 22, 2017 at 21:17 UTC
    Hi lakshmikant,

    going into a completely different direction, a one-liner doing the job:

    $ echo 'heaven > heavenly > heavenns > abc > heavenns > heavennly' | perl -nE 'BEGIN {$nr = shift;} chomp; say length $_ i +f $. == $nr;' 4 3
      He! no need of BEGIN block nor say and chomp

      perl -lne  "print length and exit if $. == 4"

      the above will work with data passed via pipe and also with a filename passed as argument.

      L*

      There are no rules, there are no thumbs..
      Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
        Yes, Discipulus, no need for a begin block because you're hard coding the line number, whereas I wanted to pass it as an argument to the script and therefore needed to retrieve it (only once). Now, of course, for a one-liner, you might as well hard code the line number, it doesn't make a big difference.
Re: how to find the length of any line of file
by karlgoethebier (Abbot) on Nov 25, 2017 at 13:01 UTC

    Try also this variations:

    #!/usr/bin/env perl use strict; use warnings; use feature qw(say); use Path::Tiny; my $file = $ARGV[0]; while (<>) { chomp; say length; } say q(--); open my $fh, q(<), $file or die $!; while (<$fh>) { chomp; say length; } close $fh; say q(--); say length for path($file)->lines( { chomp => 1 } ); __END__ karls-mac-mini:monks karl$ ./lenght.pl file.txt 6 8 8 3 8 9 -- 6 8 8 3 8 9 -- 6 8 8 3 8 9

    Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Re: how to find the length of any line of file
by FreeBeerReekingMonk (Deacon) on Nov 24, 2017 at 19:40 UTC
    length() by default counts bytes, even if you have multibyte characters (UTF8/unicode) in your file.

    For unicode lines to be counted correctly you need to open the file you are about to read with "encoding(UTF-8)" and if you want to print it out, you need to use "use utf8;" pragma.

    #!/usr/bin/perl use utf8; use Encode; use strict; use warnings; open(FF, "<:encoding(UTF-8)",'unicode.txt'); while(<FF>){ chomp; my $l = length($_); my $str = "linenr=$. length=$l $_ \n"; if(utf8::is_utf8($str)){ # get rid of the wide character warning print encode('utf-8', $str); }else{ print $str; } } close(FF);

    Now it could be your file is encoded in something else than UTF8 (like UTF16), so this might not be your solution yet.

    See also how-do-i-find-the-length-of-a-unicode-string-in-perl

    edit note: Edited the response to be more precise, as Choroba suggested.

      That's very imprecise.

      #! /usr/bin/perl use warnings; use strict; use feature qw{ say }; my $string = "\N{LATIN SMALL LETTER A WITH GRAVE}"; say length $string; # 1 { use bytes; say length $string; # 2 } open my $OUT, '>:utf8', '1' or die $!; print {$OUT} $string; close $OUT; no utf8; open my $IN, '<:utf8', '1' or die $!; my $char = <$IN>; say length $char; # 1 say $char eq $string; # 1 use utf8; open $IN, '<', '1' or die $!; my $bytes = <$IN>; say length $bytes; # 2

      utf8 tells Perl that the source code uses UTF-8. length is sensitive to bytes and to the UTF8 flag of its argument.

      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,