Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Length and Chomp ??

by snape (Pilgrim)
on Aug 18, 2009 at 20:39 UTC ( [id://789583]=perlquestion: print w/replies, xml ) Need Help??

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

hi, I am new to perl programming and have a doubt on checking the length and chomp of the scalar variable. My code is as follows :-
#!/usr/bin/perl -w use strict; use warnings; print "Enter the string ="; my $str = <STDIN>; print "Enter the size ="; my $n = <STDIN>; print "The Length of the string = ",length($str); if ($n <= length($str)){ my $x = pretty_print($str,$n); print "\nThe substring is = ",$x; } else{ print"\nThe length of the string is shorter than the size "; } sub pretty_print{ my ($dna,$len) = @_; my $substring = substr($dna,0,$len); return $substring; }
When I am trying to run it. For ex:
Enter the string =snape Enter the size =4 The Length of the string = 6 The substring is = snap
I am not sure why I am getting my length as 6 and not 5. I have tried with various examples but I am getting the length as one more than the actual length. Also, when I am trying chomp the $str after the 7th line, I am getting the length as 1. Can you please let me know the reasons regarding it ? Thanks.

Replies are listed 'Best First'.
Re: Length and Chomp ??
by Tanktalus (Canon) on Aug 18, 2009 at 20:46 UTC

    The code my $str = <STDIN>; graps "snape\n" - it includes the newline. That's the extra character. It's often helpful to print out your string, but do so in a way that shows hidden whitespace. I usually do it like this: print "str = [$str]\n"; - this puts brackets around it so that I can see if there are spaces or newlines at the end.

    If I add chomp after the input for $str, I'm not getting any problem - I think you might be calling it as $str = chomp $str which is wrong. Just call chomp $str; like this:

    #!/usr/bin/perl -w use strict; use warnings; print "Enter the string ="; my $str = <STDIN>; chomp $str; #### here is the call to chomp print "Enter the size ="; my $n = <STDIN>; print "The Length of the string = ",length($str); if ($n <= length($str)){ my $x = pretty_print($str,$n); print "\nThe substring is = ",$x; } else{ print"\nThe length of the string is shorter than the size "; } sub pretty_print{ my ($dna,$len) = @_; my $substring = substr($dna,0,$len); return $substring; }
    So close :-)

      thanks everyone for the replies..
Re: Length and Chomp ??
by kennethk (Abbot) on Aug 18, 2009 at 20:49 UTC
    The length issue you encountering comes about because the string you input is terminated with the newline character (\n), hence its length is 5 visible characters plus the newline. If you print $str, you will see the cursor advance a line. You should be able to fix it by inserting the following line after line 7:

    chomp $str;

    However, it seems like you already knew that, so I can only assume you are using chomp wrong. Since you say that your string ends up with a length of 1, I'd wager your code is

    $str = chomp $str; #Wrong!

    chomp magically acts upon the arguments and does not require you to reassign.

Re: Length and Chomp ??
by lostjimmy (Chaplain) on Aug 18, 2009 at 20:51 UTC

    The reason you get 6 instead of 5 is because the value of $str is "snape\n". That newline is the sixth character.

    I imagine that what you were doing with chomp was something like $str = chomp $str. This is incorrect. chomp will return the number of newlines removed from the end of the string, so you actually end up assigning "1" to $str, which indeed does have a length of 1.

Re: Length and Chomp ??
by biohisham (Priest) on Aug 18, 2009 at 21:01 UTC
    the length function returns the length (in bytes), your code is fine but you haven't chomped the new-line character (\n) which is embedded into the string the moment you press the return key.

    The Return key press would be treated as part of the input and you have to trim it using chomp before going further. chomp after the 7th line worked just fine for me!!!

    use strict; use warnings; print "Enter the string ="; my $str = <STDIN>; chomp $str; print "Enter the size ="; my $n = <STDIN>; chomp $n;

    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
      the length function returns the length (in bytes)

      No, it does not. It returns the number of characters found in the argument (or $_ when called without an argument). See length.

      Note that length counts every character, including control characters like CR, LF, and TAB, and not just printable characters.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        Exact and precise it is when you said that length does count every character including control characters. But citing the same perldoc for length I have "If the EXPR is in Unicode, you will get the number of characters, not the number of bytes." which means, if we look at it the other way around and negate this statement we would reach to "if the EXPR was otherwise not in Unicode, a strong implication is embedded that we'd get its length in bytes instead of characters".

        Update: I had the notion that one character can be represented by one byte in Programming, this has been more solidified after afoken gracious contribution underneath.

        Hence, what you said, that we'd get the number of characters holds true for Unicode values, and what I replied when I said that length is byte length for characters not in Unicode holds true too since characters are bytes for those values not in unicode :).


        Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
Re: Length and Chomp ??
by vitoco (Hermit) on Aug 18, 2009 at 21:48 UTC
    I am not sure why I am getting my length as 6 and not 5.

    Sometimes, usually on DOS/Windows boxes, the "newline" from input has length of 2 bytes: CR (carriage return or "\r") and LF (line feed or "\n"). chomp eats both at the same time.

      Actually Perl converts DOS/Windows newline pairs to/from a single \n during I/O so the rest of the Perl internals need know nothing of the host OS line end conventions.


      True laziness is hard work

      No. The only way chomp would remove two characters is if $/ was two characters long, and $/ is \n by default in Windows.

      >ver Microsoft Windows XP [Version 5.1.2600] >perl -le"print length $/" 1 >perl -le"$,=' '; print map { uc unpack 'H*', $_ } $/=~/./sg" 0A

      The reason this isn't a problem is that the PerlIO layer :crlf is used by default in Windows, and that layer converts CRLF to LF on read and LF to CRLF on write.

      >>foo echo foo >debug foo -rcx CX 0005 : -d100 l5 0B0B:0100 66 6F 6F 0D 0A foo.. -q >perl -le"print length <>" foo 4 >perl -le"$,=' '; print map { uc unpack 'H*', $_ } <>=~/./sg" foo 66 6F 6F 0A

      Builds of Perl without PerlIO (i.e. before 5.8) use the underlying C library, and it does the same thing.

Re: Length and Chomp ??
by Marshall (Canon) on Aug 19, 2009 at 07:57 UTC
    Some wise Monks have shown what length($x) does.
    I will show how to use this in a command line application.

    First, what starts it and ends it goes right at the front!
    We prompt for some input (the string) and give a graceful way to stop (like Q, q, quit QUIT).

    After that part, we re-prompt without error message if input line is blank.
    Then we clean up the input line as users often put spaces around things. This part along the way cleans up all this "\n" stuff.

    Now we enter the 2nd level prompt for the "size".
    Same sort of things happen... but we detect and report and re-prompt if something isn't quite right.

    I could have written the unless() as an if(). That is a matter of choice and style. However, I do think that the way that I indent these clauses is very good (my opinion). I believe that the "lining up" and spacing of this makes a difference. You can do it this way with either "unless" or "if".

    Then we come to the "print". That print won't fail mainly because we know that $size is "good".

    This code is pretty typical of UI code...lots of code that finally gets around to a few statements that actually "do something".

    Oh, I think it is worthy of notice that there aren't any tricky <CR><LF> vs just <LF> things in the code below.

    #!/usr/bin/perl -w use strict; while ( (print "Enter the string(or Quit): "), (my $line = <STDIN>) !~ /^\s*q(uit)?\s*$/i ) { next if ($line =~ m/^\s*$/); #re-prompt if blank line $line =~ s/^\s*//; #delete leading spaces $line =~ s/\s$//; #delete trailing spaces print "Enter the Sub-string size: "; my $size = (<STDIN>); unless( ($size =~ m/^\s*\d\s*$/) #only single digit && (length($line) >= $size) #only valid context ) { print "Invalid size, must be a single positive digit\n"; print " and less than or equal to: ",length($line),"\n"; next; } print "output: ",substr($line,0,$size),"\n"; } __END__ Example Output: C:\TEMP>perlcommand.pl Enter the string(or Quit): asdf Enter the Sub-string size: 8 Invalid size, must be a single positive digit and less than or equal to: 4 Enter the string(or Quit): asdf Enter the Sub-string size: -23 Invalid size, must be a single positive digit and less than or equal to: 4 Enter the string(or Quit): asdf Enter the Sub-string size: 2 output: as Enter the string(or Quit): assf Enter the Sub-string size: 4 output: assf Enter the string(or Quit): q
Re: Length and Chomp ??
by sanku (Beadle) on Aug 21, 2009 at 12:55 UTC
    hi, In perl normally <STDIN> will have a single white space at the end of the input value to remove it we can use the chomp() function. So, if you include chomp() function in your code then it will show the correct length.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://789583]
Approved by kennethk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (5)
As of 2024-04-23 20:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found