Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Print Behavior with Carriage Return

by parapunker81 (Novice)
on Jan 05, 2020 at 03:37 UTC ( [id://11110962]=perlquestion: print w/replies, xml ) Need Help??

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

Greetings,

I came across some odd behavior when using the print function and I was curious to see if someone could explain to me why it happened. In my script, I read in a file that contained lines with two strings connected with an equal sign (e.g. string1=string2).

As I read in each line, I chomped off the newline character at the end, split on the equal sign, and then created a hash where the key was the second string and the value was the first.

I would then loop through the hash like this:

foreach my $item (sort keys %hash){ print "The $item is $hash{$item}\n"; }
I was expecting it to print:

The key is value

But what I got was:

is value

After pulling my hair out, I finally realized that the file I was reading in was created in Windows so each line ended with a carriage return. The chomp only removed the \n and left the \r. So each key had a \r at the end of it.

Once I removed the \r character it printed out just fine.

My question is why did the print function not print anything before the \r character?

Thanks!

Replies are listed 'Best First'.
Re: Print Behavior with Carriage Return
by tybalt89 (Monsignor) on Jan 05, 2020 at 03:48 UTC

    It did, but the \r moves the cursor to the start of the line, so it was overwritten.

Re: Print Behavior with Carriage Return
by johngg (Canon) on Jan 05, 2020 at 12:33 UTC

    Note that you can open a file with CRLF line endings for reading with the :crlf IO layer. chomp will then remove both line ending characters.

    johngg@shiraz:~/perl/Monks$ perl -Mstrict -Mwarnings -MData::Dumper -E + ' my $fileStr = qq{val1=key1\r\nval2=key2\r\nval3=key3\r\n}; open my $inFH, q{<:crlf}, \ $fileStr or die $!; my %hash; while ( <$inFH> ) { chomp; my( $v, $k ) = split m{=}; $hash{ $k } = $v; } close $inFH or die $!; print Data::Dumper ->new( [ \ %hash ], [ qw{ *hash } ] ) ->Sortkeys( 1 ) ->Dumpxs();' %hash = ( 'key1' => 'val1', 'key2' => 'val2', 'key3' => 'val3' );

    I hope this is helpful.

    Cheers,

    JohnGG

      chomp will then remove both line ending characters.

      Nitpick: I/O layers don't change the behavior of chomp, it will continue to remove $/, which is typically one character, "\n", even on Windows. The I/O layer converts \r\n to \n when reading, so the strings end in just "\n" before they are even touched by chomp.

Re: Print Behavior with Carriage Return
by AnomalousMonk (Archbishop) on Jan 05, 2020 at 04:40 UTC

    An example:

    c:\@Work\Perl\monks>perl -wMstrict -e "use Data::Dump qw(dd); ;; $/ = qq{\n}; ;; my $input = qq{OVERWRITTEN=key\r\n}; ;; chomp $input; my ($value, $key) = split /=/, $input; dd $key; ;; my %hash = ($key, $value); print qq{The $key if not long enough is $hash{$key}}; " "key\r" if not long enough is OVERWRITTEN
    See  $/ in perlvar and chomp.


    Give a man a fish:  <%-{-{-{-<

Re: Print Behavior with Carriage Return
by LanX (Saint) on Jan 05, 2020 at 03:47 UTC
    Could you please dump the hash with Data::Dumper or even better Data::Dump?

    So we can reproduce the problem?

    I think once you see it it's obvious...

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re: Print Behavior with Carriage Return
by parapunker81 (Novice) on Jan 05, 2020 at 18:47 UTC

    Oh duh! haha Thanks everyone for your responses. It makes total sense that the \r put the cursor back to the start of the line and then the value overwrote the key. I should have thought that one through a little longer before posting :)

      I should have thought that one through a little longer before posting :)

      No worries, you asked a well-formed question, and answering those is what we're here for :-) Since it hasn't been linked to yet: Basic debugging checklist

      Did you realize that with the johngg/haukex suggestion, your issue does not need an explanation or solution. It never arises. However, this is only a good idea if your open statement opens only windows files.
      Bill
        However, this is only a good idea if your open statement opens only windows files.

        Why do you say this? The :crlf layer doesn't hurt when opening files that have LF only. The following test passes on both Linux and Windows.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (6)
As of 2024-03-28 18:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found